mirror of
https://github.com/go-gitea/gitea.git
synced 2026-08-13 23:41:16 +00:00
feat: add watch options (#37571)
Adds per-event watch options, so a user can choose which repository notifications they receive. The watch button is now a menu with four modes: participating and mentions (the unwatched state, as on GitHub), all activity, ignore, and custom, which opens a dialog to pick issues, pull requests and releases. The same dialog is reachable from the gear icon on the watched repository list. Options apply to UI notifications and to mail. The watcher, star and fork counts moved inside their buttons, so all three share one shape, and the links to those lists moved to the repository sidebar. Assignees and requested reviewers now also receive UI notifications without having commented first. Buttons and dropdown: <img width="688" height="398" alt="image" src="https://github.com/user-attachments/assets/889b567d-086f-4a06-ac67-3a4205fc63b2" /> Modal: <img width="841" height="327" alt="Screenshot 2026-08-07 at 21 10 59" src="https://github.com/user-attachments/assets/3bedbff5-9011-4f1b-91a9-e8f5c212fb5d" /> New entries in sidebar: <img width="170" height="207" alt="Screenshot 2026-08-07 at 21 13 28" src="https://github.com/user-attachments/assets/5f5150cd-f42d-4543-bd0b-7334cf4aab0e" /> Fixes: https://github.com/go-gitea/gitea/issues/17238 Ref: https://github.com/go-gitea/gitea/issues/35492 --------- Co-authored-by: bircni <bircni@icloud.com> Co-authored-by: silverwind <me@silverwind.io>
This commit is contained in:
committed by
GitHub
parent
2087d4a1a5
commit
7dbfed37eb
@@ -78,6 +78,7 @@
|
||||
{{if .IsGenerated}}<div class="secondary-info">{{ctx.Locale.Tr "repo.generated_from"}} <a href="{{(.TemplateRepo ctx).Link}}">{{(.TemplateRepo ctx).FullName}}</a></div>{{end}}
|
||||
</div>
|
||||
{{end}}
|
||||
{{if .IsSigned}}{{template "repo/watch_options_modal"}}{{end}}
|
||||
|
||||
<div class="ui container">
|
||||
<overflow-menu class="ui secondary pointing menu">
|
||||
|
||||
@@ -9,20 +9,18 @@
|
||||
{{else if $canNotForkOwn}}
|
||||
{{$forkHref = "#"}}
|
||||
{{end}}
|
||||
<div class="ui labeled button"
|
||||
<a role="button" class="ui compact small basic button {{if $.ShowForkModal}}show-modal{{end}}" href="{{$forkHref}}"
|
||||
{{if and $.IsSigned $.ShowForkModal}}data-modal="#fork-repo-modal"{{end}}
|
||||
{{if not $.IsSigned}}
|
||||
data-tooltip-content="{{ctx.Locale.Tr "repo.fork_guest_user"}}"
|
||||
{{else if $canNotForkOwn}}
|
||||
data-tooltip-content="{{ctx.Locale.Tr "repo.fork_from_self"}}"
|
||||
{{end}}
|
||||
>
|
||||
<a role="button" class="ui compact small basic button {{if $.ShowForkModal}}show-modal{{end}}" href="{{$forkHref}}"{{if and $.IsSigned $.ShowForkModal}} data-modal="#fork-repo-modal"{{end}}>
|
||||
{{svg "octicon-repo-forked"}}<span class="text not-mobile">{{ctx.Locale.Tr "repo.fork"}}</span>
|
||||
</a>
|
||||
<a class="ui basic label" href="{{$.Repository.Link}}/forks">
|
||||
{{CountFmt $.Repository.NumForks}}
|
||||
</a>
|
||||
</div>
|
||||
{{svg "octicon-repo-forked"}}
|
||||
<span class="not-mobile">{{ctx.Locale.Tr "repo.fork"}}</span>
|
||||
<span class="ui small label">{{CountFmt $.Repository.NumForks}}</span>
|
||||
</a>
|
||||
{{if $.ShowForkModal}}
|
||||
<div class="ui small modal" id="fork-repo-modal">
|
||||
<div class="header">
|
||||
|
||||
@@ -1,19 +1,14 @@
|
||||
<div class="ui labeled button" {{if not $.IsSigned}}data-tooltip-content="{{ctx.Locale.Tr "repo.star_guest_user"}}"{{end}}>
|
||||
{{$buttonText := ctx.Locale.Tr "repo.star"}}
|
||||
{{if $.IsStaringRepo}}{{$buttonText = ctx.Locale.Tr "repo.unstar"}}{{end}}
|
||||
<a role="button" class="ui compact small basic button" aria-label="{{$buttonText}}"
|
||||
{{if $.IsSigned}}
|
||||
data-fetch-method="post"
|
||||
data-fetch-url="{{$.RepoLink}}/action/{{if $.IsStaringRepo}}unstar{{else}}star{{end}}"
|
||||
data-fetch-sync="$closest(.ui.labeled.button)"
|
||||
{{else}}
|
||||
href="{{AppSubUrl}}/user/login"
|
||||
{{end}}
|
||||
>
|
||||
{{svg (Iif $.IsStaringRepo "octicon-star-fill" "octicon-star")}}
|
||||
<span class="not-mobile" aria-hidden="true">{{$buttonText}}</span>
|
||||
</a>
|
||||
<a class="ui basic label" href="{{$.RepoLink}}/stars">
|
||||
{{CountFmt .Repository.NumStars}}
|
||||
</a>
|
||||
</div>
|
||||
{{$buttonText := ctx.Locale.Tr (Iif $.IsStaringRepo "repo.unstar" "repo.star")}}
|
||||
<a role="button" class="ui compact small basic button" aria-label="{{$buttonText}}"
|
||||
{{if $.IsSigned}}
|
||||
data-fetch-method="post"
|
||||
data-fetch-url="{{$.RepoLink}}/action/{{Iif $.IsStaringRepo "unstar" "star"}}"
|
||||
{{else}}
|
||||
href="{{AppSubUrl}}/user/login"
|
||||
data-tooltip-content="{{ctx.Locale.Tr "repo.star_guest_user"}}"
|
||||
{{end}}
|
||||
>
|
||||
{{svg (Iif $.IsStaringRepo "octicon-star-fill" "octicon-star")}}
|
||||
<span class="not-mobile" aria-hidden="true">{{$buttonText}}</span>
|
||||
<span class="ui small label">{{CountFmt .Repository.NumStars}}</span>
|
||||
</a>
|
||||
|
||||
@@ -1,19 +1,53 @@
|
||||
<div class="ui labeled button" {{if not $.IsSigned}}data-tooltip-content="{{ctx.Locale.Tr "repo.watch_guest_user"}}"{{end}}>
|
||||
{{$buttonText := ctx.Locale.Tr "repo.watch"}}
|
||||
{{if $.IsWatchingRepo}}{{$buttonText = ctx.Locale.Tr "repo.unwatch"}}{{end}}
|
||||
<a role="button" class="ui compact small basic button" aria-label="{{$buttonText}}"
|
||||
{{if $.IsSigned}}
|
||||
data-fetch-method="post"
|
||||
data-fetch-url="{{$.RepoLink}}/action/{{if $.IsWatchingRepo}}unwatch{{else}}watch{{end}}"
|
||||
data-fetch-sync="$closest(.ui.labeled.button)"
|
||||
{{else}}
|
||||
href="{{AppSubUrl}}/user/login"
|
||||
{{end}}
|
||||
>
|
||||
{{svg "octicon-eye"}}
|
||||
<span class="not-mobile" aria-hidden="true">{{$buttonText}}</span>
|
||||
</a>
|
||||
<a class="ui basic label" href="{{$.RepoLink}}/watchers">
|
||||
{{CountFmt .Repository.NumWatches}}
|
||||
</a>
|
||||
{{$isIgnoring := and $.IsSigned $.Watch.IsIgnoring}}
|
||||
{{$buttonText := ctx.Locale.Tr (Iif $isIgnoring "repo.ignoring" (Iif $.IsWatchingRepo "repo.watching" "repo.watch"))}}
|
||||
{{$count := CountFmt .Repository.NumWatches}}
|
||||
<div id="repo-header-watch" class="flex-text-block">
|
||||
{{if $.IsSigned}}
|
||||
{{$isAll := and $.IsWatchingRepo $.Watch.PullRequests $.Watch.Issues $.Watch.Releases}}
|
||||
{{$isCustom := and $.IsWatchingRepo (not $isAll)}}
|
||||
{{$isParticipating := not (or $.IsWatchingRepo $isIgnoring)}}
|
||||
<button class="ui dropdown custom compact small basic button" data-global-init="initRepoWatchMenu" aria-label="{{$buttonText}}">
|
||||
{{svg (Iif $isIgnoring "octicon-eye-closed" "octicon-eye")}}
|
||||
<span class="not-mobile" aria-hidden="true">{{$buttonText}}</span>
|
||||
<span class="ui small label">{{$count}}</span>
|
||||
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
|
||||
</button>
|
||||
<div class="tippy-target">
|
||||
{{$participating := ctx.Locale.Tr "repo.watch.mode.participating"}}
|
||||
<a class="item{{if $isParticipating}} active{{end}}" role="menuitem" aria-label="{{$participating}}"
|
||||
data-fetch-method="post" data-fetch-url="{{$.RepoLink}}/action/unwatch" data-fetch-sync="$body #repo-header-watch"
|
||||
>
|
||||
{{svg "octicon-check" 16 (Iif $isParticipating "" "tw-invisible")}}
|
||||
<div>{{$participating}}<div class="tw-text-12 tw-text-text-light-2">{{ctx.Locale.Tr "repo.watch.mode.participating.desc"}}</div></div>
|
||||
</a>
|
||||
{{$all := ctx.Locale.Tr "repo.watch.mode.all"}}
|
||||
<a class="item{{if $isAll}} active{{end}}" role="menuitem" aria-label="{{$all}}"
|
||||
data-fetch-method="post" data-fetch-url="{{$.RepoLink}}/action/watch" data-fetch-sync="$body #repo-header-watch"
|
||||
>
|
||||
{{svg "octicon-check" 16 (Iif $isAll "" "tw-invisible")}}
|
||||
<div>{{$all}}<div class="tw-text-12 tw-text-text-light-2">{{ctx.Locale.Tr "repo.watch.mode.all.desc"}}</div></div>
|
||||
</a>
|
||||
{{$ignore := ctx.Locale.Tr "repo.watch.mode.ignore"}}
|
||||
<a class="item{{if $.Watch.IsIgnoring}} active{{end}}" role="menuitem" aria-label="{{$ignore}}"
|
||||
data-fetch-method="post" data-fetch-url="{{$.RepoLink}}/action/ignore" data-fetch-sync="$body #repo-header-watch"
|
||||
>
|
||||
{{svg "octicon-check" 16 (Iif $.Watch.IsIgnoring "" "tw-invisible")}}
|
||||
<div>{{$ignore}}<div class="tw-text-12 tw-text-text-light-2">{{ctx.Locale.Tr "repo.watch.mode.ignore.desc"}}</div></div>
|
||||
</a>
|
||||
{{$custom := ctx.Locale.Tr "repo.watch.mode.custom"}}
|
||||
<a class="item{{if $isCustom}} active{{end}}" role="menuitem" aria-label="{{$custom}}"
|
||||
data-global-click="onRepoWatchOptionsClick" data-url="{{$.RepoLink}}/action/watch/options"
|
||||
data-issues="{{$.Watch.Issues}}" data-pull-requests="{{$.Watch.PullRequests}}" data-releases="{{$.Watch.Releases}}"
|
||||
>
|
||||
{{svg "octicon-check" 16 (Iif $isCustom "" "tw-invisible")}}
|
||||
<div>{{$custom}}<div class="tw-text-12 tw-text-text-light-2">{{ctx.Locale.Tr "repo.watch.mode.custom.desc"}}</div></div>
|
||||
</a>
|
||||
</div>
|
||||
{{else}}
|
||||
<a role="button" class="ui compact small basic button" href="{{AppSubUrl}}/user/login" aria-label="{{$buttonText}}" data-tooltip-content="{{ctx.Locale.Tr "repo.watch_guest_user"}}">
|
||||
{{svg "octicon-eye"}}
|
||||
<span class="not-mobile" aria-hidden="true">{{$buttonText}}</span>
|
||||
<span class="ui small label">{{$count}}</span>
|
||||
</a>
|
||||
{{end}}
|
||||
</div>
|
||||
|
||||
@@ -69,5 +69,17 @@
|
||||
{{$fileSizeFields := StringUtils.Split $fileSizeFormatted " "}}
|
||||
{{svg "octicon-database"}} <b>{{ctx.Locale.PrettyNumber (index $fileSizeFields 0)}}</b> {{index $fileSizeFields 1}}
|
||||
</div>
|
||||
|
||||
{{if not .DisableStars}}
|
||||
<a class="flex-text-block muted" href="{{.RepoLink}}/stars">
|
||||
{{svg "octicon-star"}} <b>{{CountFmt .Repository.NumStars}}</b> {{ctx.Locale.Tr "repo.stars"}}
|
||||
</a>
|
||||
{{end}}
|
||||
<a class="flex-text-block muted" href="{{.RepoLink}}/watchers">
|
||||
{{svg "octicon-eye"}} <b>{{CountFmt .Repository.NumWatches}}</b> {{ctx.Locale.Tr "repo.watchers"}}
|
||||
</a>
|
||||
<a class="flex-text-block muted" href="{{.RepoLink}}/forks">
|
||||
{{svg "octicon-repo-forked"}} <b>{{CountFmt .Repository.NumForks}}</b> {{ctx.Locale.Tr "repo.forks"}}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
</h2>
|
||||
{{template "base/alert" .}}
|
||||
|
||||
<form class="ui form form-fetch-action" action="{{.Link}}" method="post" data-global-init="initReleaseEditForm"
|
||||
<form class="ui form form-fetch-action" action="{{.Link}}" id="new-release" method="post" data-global-init="initReleaseEditForm"
|
||||
data-existing-tags="{{JsonUtils.EncodeToString .Tags}}"
|
||||
data-tag-helper="{{ctx.Locale.Tr "repo.release.tag_helper"}}"
|
||||
data-tag-helper-new="{{ctx.Locale.Tr "repo.release.tag_helper_new"}}"
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
<div class="ui small modal" id="repo-watch-options-modal">
|
||||
<div class="header">{{ctx.Locale.Tr "notifications"}}</div>
|
||||
<form class="ui form form-fetch-action" method="post">
|
||||
<div class="content">
|
||||
{{range $name := StringUtils.Split "issues,pull_requests,releases" ","}}
|
||||
<div class="field">
|
||||
<div class="ui checkbox">
|
||||
<input name="{{$name}}" type="checkbox"><label>{{ctx.Locale.Tr (printf "repo.watch.options.%s" $name)}}</label>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
{{template "base/modal_actions_confirm" dict "ModalButtonTypes" "confirm"}}
|
||||
</form>
|
||||
</div>
|
||||
@@ -55,6 +55,14 @@
|
||||
<span class="tw-contents" aria-label="{{ctx.Locale.Tr "repo.forks"}}">{{svg "octicon-repo-forked" 16}}</span>
|
||||
<span {{if ge .NumForks 1000}}data-tooltip-content="{{.NumForks}}"{{end}}>{{CountFmt .NumForks}}</span>
|
||||
</a>
|
||||
{{$watch := and $.Watches (index $.Watches .ID)}}
|
||||
{{if $watch}}
|
||||
<button class="btn flex-text-inline" data-global-click="onRepoWatchOptionsClick"
|
||||
data-url="{{.Link}}/action/watch/options"
|
||||
data-issues="{{$watch.Issues}}" data-pull-requests="{{$watch.PullRequests}}" data-releases="{{$watch.Releases}}"
|
||||
data-tooltip-content="{{ctx.Locale.Tr "notifications"}}"
|
||||
>{{svg "octicon-gear" 16}}</button>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
{{$description := .DescriptionHTML ctx}}
|
||||
@@ -76,4 +84,5 @@
|
||||
{{ctx.Locale.Tr "search.no_results"}}
|
||||
</div>
|
||||
{{end}}
|
||||
{{if $.Watches}}{{template "repo/watch_options_modal"}}{{end}}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user