Add user blocking (#29028)

Fixes #17453

This PR adds the abbility to block a user from a personal account or
organization to restrict how the blocked user can interact with the
blocker. The docs explain what's the consequence of blocking a user.

Screenshots:


![grafik](https://github.com/go-gitea/gitea/assets/1666336/4ed884f3-e06a-4862-afd3-3b8aa2488dc6)


![grafik](https://github.com/go-gitea/gitea/assets/1666336/ae6d4981-f252-4f50-a429-04f0f9f1cdf1)


![grafik](https://github.com/go-gitea/gitea/assets/1666336/ca153599-5b0f-4b4a-90fe-18bdfd6f0b6b)

---------

Co-authored-by: Lauris BH <lauris@nix.lv>
This commit is contained in:
KN4CK3R
2024-03-04 09:16:03 +01:00
committed by GitHub
parent 8e12ba34ba
commit c337ff0ec7
109 changed files with 2878 additions and 548 deletions

View File

@ -0,0 +1,23 @@
<div class="ui small modal" id="block-user-modal">
<div class="header">{{ctx.Locale.Tr "user.block.title"}}</div>
<div class="content">
<div class="ui warning message">{{ctx.Locale.Tr "user.block.info"}}</div>
<form class="ui form modal-form" method="post">
{{.CsrfTokenHtml}}
<input type="hidden" name="action" value="block" />
<input type="hidden" name="blockee" class="modal-blockee" />
<div class="field">
<label>{{ctx.Locale.Tr "user.block.user_to_block"}}: <span class="text red modal-blockee-name"></span></label>
</div>
<div class="field">
<label for="block-note">{{ctx.Locale.Tr "user.block.note.title"}}</label>
<input id="block-note" name="note">
<p class="help">{{ctx.Locale.Tr "user.block.note.info"}}</p>
</div>
<div class="text right actions">
<button class="ui cancel button">{{ctx.Locale.Tr "cancel"}}</button>
<button class="ui red button">{{ctx.Locale.Tr "user.block.block"}}</button>
</div>
</form>
</div>
</div>

View File

@ -0,0 +1,83 @@
<h4 class="ui top attached header">
{{ctx.Locale.Tr "user.block.title"}}
</h4>
<div class="ui attached segment">
<p>{{ctx.Locale.Tr "user.block.info_1"}}</p>
<ul>
<li>{{ctx.Locale.Tr "user.block.info_2"}}</li>
<li>{{ctx.Locale.Tr "user.block.info_3"}}</li>
<li>{{ctx.Locale.Tr "user.block.info_4"}}</li>
<li>{{ctx.Locale.Tr "user.block.info_5"}}</li>
<li>{{ctx.Locale.Tr "user.block.info_6"}}</li>
<li>{{ctx.Locale.Tr "user.block.info_7"}}</li>
</ul>
</div>
<div class="ui segment">
<form class="ui form ignore-dirty" action="{{$.Link}}" method="post">
{{.CsrfTokenHtml}}
<input type="hidden" name="action" value="block" />
<div id="search-user-box" class="field ui fluid search input">
<input class="prompt gt-mr-3" name="blockee" placeholder="{{ctx.Locale.Tr "repo.settings.search_user_placeholder"}}" autocomplete="off" required>
<button class="ui red button">{{ctx.Locale.Tr "user.block.block"}}</button>
</div>
<div class="field">
<label>{{ctx.Locale.Tr "user.block.note.title"}}</label>
<input name="note">
<p class="help">{{ctx.Locale.Tr "user.block.note.info"}}</p>
</div>
</form>
</div>
<h4 class="ui top attached header">
{{ctx.Locale.Tr "user.block.list"}}
</h4>
<div class="ui attached segment">
<div class="flex-list">
{{range .UserBlocks}}
<div class="flex-item">
<div class="flex-item-leading">
{{ctx.AvatarUtils.Avatar .Blockee}}
</div>
<div class="flex-item-main">
<div class="flex-item-title">
<a class="item" href="{{.Blockee.HTMLURL}}">{{.Blockee.GetDisplayName}}</a>
</div>
{{if .Note}}
<div class="flex-item-body">
<i>{{ctx.Locale.Tr "user.block.note"}}:</i> {{.Note}}
</div>
{{end}}
</div>
<div class="flex-item-trailing">
<button class="ui compact mini button show-modal" data-modal="#block-user-note-modal" data-modal-modal-blockee="{{.Blockee.Name}}" data-modal-modal-note="{{.Note}}">{{ctx.Locale.Tr "user.block.note.edit"}}</button>
<form action="{{$.Link}}" method="post">
{{$.CsrfTokenHtml}}
<input type="hidden" name="action" value="unblock" />
<input type="hidden" name="blockee" value="{{.Blockee.Name}}" />
<button class="ui compact mini button">{{ctx.Locale.Tr "user.block.unblock"}}</button>
</form>
</div>
</div>
{{else}}
<div class="item">{{ctx.Locale.Tr "user.block.list.none"}}</div>
{{end}}
</div>
</div>
<div class="ui small modal" id="block-user-note-modal">
<div class="header">{{ctx.Locale.Tr "user.block.note.edit"}}</div>
<div class="content">
<form class="ui form" action="{{$.Link}}" method="post">
{{.CsrfTokenHtml}}
<input type="hidden" name="action" value="note" />
<input type="hidden" name="blockee" class="modal-blockee" />
<div class="field">
<label>{{ctx.Locale.Tr "user.block.note.title"}}</label>
<input name="note" class="modal-note" />
<p class="help">{{ctx.Locale.Tr "user.block.note.info"}}</p>
</div>
<div class="text right actions">
<button class="ui cancel button">{{ctx.Locale.Tr "cancel"}}</button>
<button class="ui primary button">{{ctx.Locale.Tr "save"}}</button>
</div>
</form>
</div>
</div>

View File

@ -27,6 +27,12 @@
</div>
<div class="extra content gt-word-break">
<ul>
{{if .UserBlocking}}
<li class="text red">{{svg "octicon-circle-slash"}} {{ctx.Locale.Tr "user.block.blocked"}}</li>
{{if .UserBlocking.Note}}
<li class="text small red">{{ctx.Locale.Tr "user.block.note"}}: {{.UserBlocking.Note}}</li>
{{end}}
{{end}}
{{if .ContextUser.Location}}
<li>
{{svg "octicon-location"}}
@ -109,18 +115,29 @@
</li>
{{end}}
{{if and .IsSigned (ne .SignedUserID .ContextUser.ID)}}
<li class="follow" hx-target="#profile-avatar-card" hx-indicator="#profile-avatar-card" >
{{if $.IsFollowing}}
<button hx-post="{{.ContextUser.HomeLink}}?action=unfollow" class="ui basic red button">
{{svg "octicon-person"}} {{ctx.Locale.Tr "user.unfollow"}}
</button>
{{else}}
<button hx-post="{{.ContextUser.HomeLink}}?action=follow" class="ui basic primary button">
{{svg "octicon-person"}} {{ctx.Locale.Tr "user.follow"}}
</button>
{{if not .UserBlocking}}
<li class="follow" hx-target="#profile-avatar-card" hx-indicator="#profile-avatar-card">
{{if $.IsFollowing}}
<button hx-post="{{.ContextUser.HomeLink}}?action=unfollow" class="ui basic red button">
{{svg "octicon-person"}} {{ctx.Locale.Tr "user.unfollow"}}
</button>
{{else}}
<button hx-post="{{.ContextUser.HomeLink}}?action=follow" class="ui basic primary button">
{{svg "octicon-person"}} {{ctx.Locale.Tr "user.follow"}}
</button>
{{end}}
</li>
{{end}}
</li>
<li>
{{if not .UserBlocking}}
<a class="muted show-modal" href="#" data-modal="#block-user-modal" data-modal-modal-blockee="{{.ContextUser.Name}}" data-modal-modal-blockee-name="{{.ContextUser.GetDisplayName}}" data-modal-modal-form.action="{{AppSubUrl}}/user/settings/blocked_users">{{ctx.Locale.Tr "user.block.block.user"}}</a>
{{else}}
<a class="muted" href="{{AppSubUrl}}/user/settings/blocked_users">{{ctx.Locale.Tr "user.block.unblock"}}</a>
{{end}}
</li>
{{end}}
</ul>
</div>
</div>
{{template "shared/user/block_user_dialog" .}}