mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2025-03-26 21:43:00 +00:00
Add new 'Report abuse' form and links for user profile, repository page, issues, pulls and comments.
This commit is contained in:
parent
bca6ac6f6c
commit
248e2d3861
18 changed files with 233 additions and 63 deletions
|
@ -14,8 +14,8 @@ import (
|
||||||
// CommentData represents a trimmed down comment that is used for preserving
|
// CommentData represents a trimmed down comment that is used for preserving
|
||||||
// only the fields needed for abusive content reports (mainly string fields).
|
// only the fields needed for abusive content reports (mainly string fields).
|
||||||
type CommentData struct {
|
type CommentData struct {
|
||||||
OriginalAuthor string // TODO: decide if this is needed
|
OriginalAuthor string // TODO: decide if this is useful
|
||||||
TreePath string // TODO: decide if this is needed
|
TreePath string // TODO: decide if this is useful
|
||||||
Content string
|
Content string
|
||||||
ContentVersion int
|
ContentVersion int
|
||||||
CreatedUnix timeutil.TimeStamp
|
CreatedUnix timeutil.TimeStamp
|
||||||
|
|
|
@ -25,8 +25,17 @@ const (
|
||||||
ReportStatusTypeIgnored // 3
|
ReportStatusTypeIgnored // 3
|
||||||
)
|
)
|
||||||
|
|
||||||
// AbuseCategoryType defines the categories in which a user can include the reported content.
|
type (
|
||||||
type AbuseCategoryType int //revive:disable-line:exported
|
// AbuseCategoryType defines the categories in which a user can include the reported content.
|
||||||
|
AbuseCategoryType int //revive:disable-line:exported
|
||||||
|
|
||||||
|
// AbuseCategoryItem defines a pair of value and it's corresponding translation key
|
||||||
|
// (used when new reports are submitted).
|
||||||
|
AbuseCategoryItem struct {
|
||||||
|
Value AbuseCategoryType
|
||||||
|
TranslationKey string
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
AbuseCategoryTypeSpam AbuseCategoryType = iota + 1 // 1
|
AbuseCategoryTypeSpam AbuseCategoryType = iota + 1 // 1
|
||||||
|
@ -35,6 +44,17 @@ const (
|
||||||
AbuseCategoryTypeOtherViolations // 4 (Other violations of platform rules)
|
AbuseCategoryTypeOtherViolations // 4 (Other violations of platform rules)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// GetAbuseCategoriesList returns a list of pairs with the available abuse category types
|
||||||
|
// and their corresponding translation keys
|
||||||
|
func GetAbuseCategoriesList() []AbuseCategoryItem {
|
||||||
|
return []AbuseCategoryItem{
|
||||||
|
{AbuseCategoryTypeSpam, "moderation.abuse_category.spam"},
|
||||||
|
{AbuseCategoryTypeMalware, "moderation.abuse_category.malware"},
|
||||||
|
{AbuseCategoryTypeIllegalContent, "moderation.abuse_category.illegal_content"},
|
||||||
|
{AbuseCategoryTypeOtherViolations, "moderation.abuse_category.other_violations"},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ReportedContentType defines the types of content that can be reported
|
// ReportedContentType defines the types of content that can be reported
|
||||||
// (i.e. user/organization profile, repository, issue/pull, comment).
|
// (i.e. user/organization profile, repository, issue/pull, comment).
|
||||||
type ReportedContentType int //revive:disable-line:exported
|
type ReportedContentType int //revive:disable-line:exported
|
||||||
|
@ -97,6 +117,15 @@ func alreadyReportedBy(ctx context.Context, doerID int64, contentType ReportedCo
|
||||||
return reported
|
return reported
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ReportAbuse(ctx context.Context, report *AbuseReport) error {
|
||||||
|
if report.ContentType == ReportedContentTypeUser && report.ReporterID == report.ContentID {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return reportAbuse(ctx, report)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
// ReportUser creates a new abuse report regarding the user with the provided reportedUserID.
|
// ReportUser creates a new abuse report regarding the user with the provided reportedUserID.
|
||||||
func ReportUser(ctx context.Context, reporterID int64, reportedUserID int64, remarks string) error {
|
func ReportUser(ctx context.Context, reporterID int64, reportedUserID int64, remarks string) error {
|
||||||
if reporterID == reportedUserID {
|
if reporterID == reportedUserID {
|
||||||
|
@ -148,6 +177,7 @@ func ReportComment(ctx context.Context, reporterID int64, commentID int64, remar
|
||||||
|
|
||||||
return reportAbuse(ctx, report)
|
return reportAbuse(ctx, report)
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
func reportAbuse(ctx context.Context, report *AbuseReport) error {
|
func reportAbuse(ctx context.Context, report *AbuseReport) error {
|
||||||
if alreadyReportedBy(ctx, report.ReporterID, report.ContentType, report.ContentID) {
|
if alreadyReportedBy(ctx, report.ReporterID, report.ContentType, report.ContentID) {
|
||||||
|
@ -156,8 +186,6 @@ func reportAbuse(ctx context.Context, report *AbuseReport) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
report.Status = ReportStatusTypeOpen
|
report.Status = ReportStatusTypeOpen
|
||||||
report.Category = AbuseCategoryTypeOtherViolations // TODO: replace with user's selection
|
|
||||||
|
|
||||||
_, err := db.GetEngine(ctx).Insert(report)
|
_, err := db.GetEngine(ctx).Insert(report)
|
||||||
|
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -938,6 +938,8 @@ func UpdateUserCols(ctx context.Context, u *User, cols ...string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the user was reported as abusive and any of the columns being updated is relevant
|
||||||
|
// for moderation purposes a shadow copy should be created before first update.
|
||||||
if err := IfNeededCreateShadowCopyForUser(ctx, u, cols...); err != nil {
|
if err := IfNeededCreateShadowCopyForUser(ctx, u, cols...); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -3964,10 +3964,23 @@ filepreview.truncated = Preview has been truncated
|
||||||
report = Report
|
report = Report
|
||||||
;already_reported = Already reported
|
;already_reported = Already reported
|
||||||
report_abuse = Report abuse
|
report_abuse = Report abuse
|
||||||
report_comment = Report comment
|
report_content = Report content
|
||||||
|
report_abuse_form.header = Report abuse to administrator
|
||||||
|
report_abuse_form.details = This form should be used to report users who create spam profiles, repositories, issues, comments or behave inappropriately.
|
||||||
|
report_abuse_form.invalid = Invalid arguments
|
||||||
|
|
||||||
|
abuse_category = Category
|
||||||
|
abuse_category.placeholder = Please select a category
|
||||||
|
abuse_category.spam = Spam
|
||||||
|
abuse_category.malware = Malware
|
||||||
|
abuse_category.illegal_content = Illegal content
|
||||||
|
abuse_category.other_violations = Other violations of platform rules
|
||||||
|
|
||||||
report_remarks = Remarks
|
report_remarks = Remarks
|
||||||
report_user = Report user
|
report_remarks.placeholder = Please provide some details regarding the abuse you are reporting.
|
||||||
report_user.detail = Are you sure you that this user committed an abuse and you want to report them?<br>TODO: Reason dropdown<br>TODO: Remarks textarea
|
|
||||||
|
submit_report = Submit report
|
||||||
|
reported_thank_you = Thank you for your report. An administrator will look into it shortly.
|
||||||
|
|
||||||
[translation_meta]
|
[translation_meta]
|
||||||
test = This is a test string. It is not displayed in Forgejo UI but is used for testing purposes. Feel free to enter "ok" to save time (or a fun fact of your choice) to hit that sweet 100% completion mark :)
|
test = This is a test string. It is not displayed in Forgejo UI but is used for testing purposes. Feel free to enter "ok" to save time (or a fun fact of your choice) to hit that sweet 100% completion mark :)
|
||||||
|
|
89
routers/web/moderation/report.go
Normal file
89
routers/web/moderation/report.go
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
// Copyright 2025 The Forgejo Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
package moderation
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/models/moderation"
|
||||||
|
"code.gitea.io/gitea/modules/base"
|
||||||
|
"code.gitea.io/gitea/modules/log"
|
||||||
|
"code.gitea.io/gitea/modules/web"
|
||||||
|
"code.gitea.io/gitea/services/context"
|
||||||
|
"code.gitea.io/gitea/services/forms"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
tplSubmitAbuseReport base.TplName = "moderation/new_abuse_report"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewReport renders the page for new abuse reports.
|
||||||
|
func NewReport(ctx *context.Context) {
|
||||||
|
contentID := ctx.FormInt64("id")
|
||||||
|
if contentID <= 0 {
|
||||||
|
ctx.RenderWithErr(ctx.Tr("moderation.report_abuse_form.invalid"), tplSubmitAbuseReport, nil)
|
||||||
|
log.Warn("The content ID is expected to be an integer greater that 0; the provided value is %d.", contentID)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
contentTypeString := ctx.FormString("type")
|
||||||
|
var contentType moderation.ReportedContentType
|
||||||
|
switch contentTypeString {
|
||||||
|
case "user", "org":
|
||||||
|
contentType = moderation.ReportedContentTypeUser
|
||||||
|
case "repo":
|
||||||
|
contentType = moderation.ReportedContentTypeRepository
|
||||||
|
case "issue", "pull":
|
||||||
|
contentType = moderation.ReportedContentTypeIssue
|
||||||
|
case "comment":
|
||||||
|
contentType = moderation.ReportedContentTypeComment
|
||||||
|
default:
|
||||||
|
ctx.RenderWithErr(ctx.Tr("moderation.report_abuse_form.invalid"), tplSubmitAbuseReport, nil)
|
||||||
|
log.Warn("The provided content type `%s` is not among the expected values.", contentTypeString)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
setContextDataAndRender(ctx, contentType, contentID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// setContextDataAndRender adds some values into context data and renders the new abuse report page.
|
||||||
|
func setContextDataAndRender(ctx *context.Context, contentType moderation.ReportedContentType, contentID int64) {
|
||||||
|
ctx.Data["Title"] = ctx.Tr("moderation.report_abuse")
|
||||||
|
ctx.Data["ContentID"] = contentID
|
||||||
|
ctx.Data["ContentType"] = contentType
|
||||||
|
ctx.Data["AbuseCategories"] = moderation.GetAbuseCategoriesList()
|
||||||
|
ctx.Data["CancelLink"] = ctx.Doer.DashboardLink()
|
||||||
|
ctx.HTML(http.StatusOK, tplSubmitAbuseReport)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreatePost handles the POST for creating a new abuse report.
|
||||||
|
func CreatePost(ctx *context.Context) {
|
||||||
|
form := *web.GetForm(ctx).(*forms.ReportAbuseForm)
|
||||||
|
|
||||||
|
if form.ContentID <= 0 || form.ContentType == 0 {
|
||||||
|
ctx.RenderWithErr(ctx.Tr("moderation.report_abuse_form.invalid"), tplSubmitAbuseReport, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if ctx.HasError() {
|
||||||
|
setContextDataAndRender(ctx, form.ContentType, form.ContentID)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
report := moderation.AbuseReport{
|
||||||
|
ReporterID: ctx.Doer.ID,
|
||||||
|
ContentType: form.ContentType,
|
||||||
|
ContentID: form.ContentID,
|
||||||
|
Category: form.AbuseCategory,
|
||||||
|
Remarks: form.Remarks,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := moderation.ReportAbuse(ctx, &report); err != nil {
|
||||||
|
ctx.ServerError("Something went wrong while trying to submit the new abuse report.", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.Flash.Success(ctx.Tr("moderation.reported_thank_you"))
|
||||||
|
ctx.Redirect(ctx.Doer.DashboardLink())
|
||||||
|
}
|
|
@ -13,7 +13,7 @@ import (
|
||||||
|
|
||||||
activities_model "code.gitea.io/gitea/models/activities"
|
activities_model "code.gitea.io/gitea/models/activities"
|
||||||
"code.gitea.io/gitea/models/db"
|
"code.gitea.io/gitea/models/db"
|
||||||
"code.gitea.io/gitea/models/moderation"
|
|
||||||
repo_model "code.gitea.io/gitea/models/repo"
|
repo_model "code.gitea.io/gitea/models/repo"
|
||||||
user_model "code.gitea.io/gitea/models/user"
|
user_model "code.gitea.io/gitea/models/user"
|
||||||
"code.gitea.io/gitea/modules/base"
|
"code.gitea.io/gitea/modules/base"
|
||||||
|
@ -360,8 +360,6 @@ func Action(ctx *context.Context) {
|
||||||
err = user_service.BlockUser(ctx, ctx.Doer.ID, ctx.ContextUser.ID)
|
err = user_service.BlockUser(ctx, ctx.Doer.ID, ctx.ContextUser.ID)
|
||||||
case "unblock":
|
case "unblock":
|
||||||
err = user_model.UnblockUser(ctx, ctx.Doer.ID, ctx.ContextUser.ID)
|
err = user_model.UnblockUser(ctx, ctx.Doer.ID, ctx.ContextUser.ID)
|
||||||
case "report":
|
|
||||||
err = moderation.ReportUser(ctx, ctx.Doer.ID, ctx.ContextUser.ID, "{remarks not implemented}")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
// Copyright 2017 The Gitea Authors. All rights reserved.
|
// Copyright 2017 The Gitea Authors. All rights reserved.
|
||||||
|
// Copyright 2025 The Forgejo Authors. All rights reserved.
|
||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
package web
|
package web
|
||||||
|
@ -33,6 +34,7 @@ import (
|
||||||
"code.gitea.io/gitea/routers/web/feed"
|
"code.gitea.io/gitea/routers/web/feed"
|
||||||
"code.gitea.io/gitea/routers/web/healthcheck"
|
"code.gitea.io/gitea/routers/web/healthcheck"
|
||||||
"code.gitea.io/gitea/routers/web/misc"
|
"code.gitea.io/gitea/routers/web/misc"
|
||||||
|
"code.gitea.io/gitea/routers/web/moderation"
|
||||||
"code.gitea.io/gitea/routers/web/org"
|
"code.gitea.io/gitea/routers/web/org"
|
||||||
org_setting "code.gitea.io/gitea/routers/web/org/setting"
|
org_setting "code.gitea.io/gitea/routers/web/org/setting"
|
||||||
"code.gitea.io/gitea/routers/web/repo"
|
"code.gitea.io/gitea/routers/web/repo"
|
||||||
|
@ -479,6 +481,9 @@ func registerRoutes(m *web.Route) {
|
||||||
m.Get("/search", repo.SearchIssues)
|
m.Get("/search", repo.SearchIssues)
|
||||||
}, reqSignIn)
|
}, reqSignIn)
|
||||||
|
|
||||||
|
m.Get("/-/abuse_reports/new", moderation.NewReport, reqSignIn)
|
||||||
|
m.Post("/-/abuse_reports/new", web.Bind(forms.ReportAbuseForm{}), moderation.CreatePost, reqSignIn)
|
||||||
|
|
||||||
m.Get("/pulls", reqSignIn, user.Pulls)
|
m.Get("/pulls", reqSignIn, user.Pulls)
|
||||||
m.Get("/milestones", reqSignIn, reqMilestonesDashboardPageEnabled, user.Milestones)
|
m.Get("/milestones", reqSignIn, reqMilestonesDashboardPageEnabled, user.Milestones)
|
||||||
|
|
||||||
|
|
28
services/forms/report_abuse.go
Normal file
28
services/forms/report_abuse.go
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
// Copyright 2025 The Forgejo Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
package forms
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/models/moderation"
|
||||||
|
"code.gitea.io/gitea/modules/web/middleware"
|
||||||
|
"code.gitea.io/gitea/services/context"
|
||||||
|
|
||||||
|
"code.forgejo.org/go-chi/binding"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ReportAbuseForm is used to interact with the UI of the form that submits new abuse reports.
|
||||||
|
type ReportAbuseForm struct {
|
||||||
|
ContentID int64
|
||||||
|
ContentType moderation.ReportedContentType
|
||||||
|
AbuseCategory moderation.AbuseCategoryType `binding:"Required" locale:"moderation.abuse_category"`
|
||||||
|
Remarks string `binding:"Required;MinSize(20);MaxSize(500)" preprocess:"TrimSpace" locale:"moderation.report_remarks"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate validates the fields of ReportAbuseForm.
|
||||||
|
func (f *ReportAbuseForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||||
|
ctx := context.GetValidateContext(req)
|
||||||
|
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||||
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
// Copyright 2023 The Gitea Authors. All rights reserved.
|
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||||
|
// Copyright 2025 The Forgejo Authors. All rights reserved.
|
||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
package user
|
package user
|
||||||
|
@ -216,6 +217,7 @@ func deleteUser(ctx context.Context, u *user_model.User, purge bool) (err error)
|
||||||
}
|
}
|
||||||
// ***** END: ExternalLoginUser *****
|
// ***** END: ExternalLoginUser *****
|
||||||
|
|
||||||
|
// If the user was reported as abusive, a shadow copy should be created before deletion.
|
||||||
if err = user_model.IfNeededCreateShadowCopyForUser(ctx, u); err != nil {
|
if err = user_model.IfNeededCreateShadowCopyForUser(ctx, u); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
43
templates/moderation/new_abuse_report.tmpl
Normal file
43
templates/moderation/new_abuse_report.tmpl
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
{{template "base/head" .}}
|
||||||
|
<div role="main" aria-label="{{.Title}}" class="page-content organization new org">
|
||||||
|
<div class="ui middle very relaxed page grid">
|
||||||
|
<div class="column">
|
||||||
|
<form class="ui form" action="{{.Link}}" method="post">
|
||||||
|
{{.CsrfTokenHtml}}
|
||||||
|
<h3 class="ui top attached header">
|
||||||
|
{{ctx.Locale.Tr "moderation.report_abuse_form.header"}}
|
||||||
|
</h3>
|
||||||
|
<div class="ui attached segment">
|
||||||
|
{{template "base/alert" .}}
|
||||||
|
<p class="ui center">{{ctx.Locale.Tr "moderation.report_abuse_form.details"}}</p>
|
||||||
|
|
||||||
|
<input type="hidden" name="content_id" value="{{.ContentID}}" />
|
||||||
|
<input type="hidden" name="content_type" value="{{.ContentType}}" />
|
||||||
|
|
||||||
|
<fieldset>
|
||||||
|
<label{{if .Err_AbuseCategory}} class="error"{{end}}>
|
||||||
|
{{ctx.Locale.Tr "moderation.abuse_category"}}
|
||||||
|
<select class="ui selection dropdown" id="abuse_category" name="abuse_category" required autofocus>
|
||||||
|
<option value="">{{ctx.Locale.Tr "moderation.abuse_category.placeholder"}}</option>
|
||||||
|
{{range $cat := .AbuseCategories}}
|
||||||
|
<option value="{{$cat.Value}}"{{if eq $.abuse_category $cat.Value}} selected{{end}}>{{ctx.Locale.Tr $cat.TranslationKey}}</option>
|
||||||
|
{{end}}
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
<label{{if .Err_Remarks}} class="error"{{end}}>
|
||||||
|
{{ctx.Locale.Tr "moderation.report_remarks"}}
|
||||||
|
<textarea id="remarks" name="remarks" required minlength="20" maxlength="500" placeholder="{{ctx.Locale.Tr "moderation.report_remarks.placeholder"}}">{{.remarks}}</textarea>
|
||||||
|
</label>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
<div class="divider"></div>
|
||||||
|
<div class="text right actions">
|
||||||
|
<a class="ui cancel button" href="{{$.CancelLink}}">{{ctx.Locale.Tr "cancel"}}</a>
|
||||||
|
<button class="ui primary button"{{if not .ContentID}} disabled{{end}}>{{ctx.Locale.Tr "moderation.submit_report"}}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{template "base/footer" .}}
|
|
@ -67,6 +67,12 @@
|
||||||
{{if not $.DisableForks}}
|
{{if not $.DisableForks}}
|
||||||
{{template "repo/header_fork" $}}
|
{{template "repo/header_fork" $}}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
<button class="ui small compact jump dropdown icon button"{{if not $.IsSigned}} disabled{{end}} data-tooltip-content="{{ctx.Locale.Tr "repo.more_operations"}}" aria-label="{{ctx.Locale.Tr "toggle_menu"}}">
|
||||||
|
{{svg "octicon-kebab-horizontal"}}
|
||||||
|
<div class="menu top left">
|
||||||
|
<a class="item context" href="/-/abuse_reports/new?type=repo&id={{$.Repository.ID}}">{{ctx.Locale.Tr "moderation.report_content"}}</a>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -172,8 +172,6 @@
|
||||||
|
|
||||||
{{template "repo/issue/view_content/reference_issue_dialog" .}}
|
{{template "repo/issue/view_content/reference_issue_dialog" .}}
|
||||||
|
|
||||||
{{template "repo/issue/view_content/report_comment_dialog" .}}
|
|
||||||
|
|
||||||
<div class="tw-hidden" id="no-content">
|
<div class="tw-hidden" id="no-content">
|
||||||
<span class="no-content">{{ctx.Locale.Tr "repo.issues.no_content"}}</span>
|
<span class="no-content">{{ctx.Locale.Tr "repo.issues.no_content"}}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -24,8 +24,12 @@
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if and .ctxData.IsSigned (not .IsCommentPoster)}}
|
{{if and .ctxData.IsSigned (not .IsCommentPoster)}}
|
||||||
|
{{$contentType := "comment"}}
|
||||||
|
{{if eq .item .ctxData.Issue}}
|
||||||
|
{{if .ctxData.Issue.IsPull}} {{$contentType = "pull"}} {{else}} {{$contentType = "issue"}} {{end}}
|
||||||
|
{{end}}
|
||||||
<div class="divider"></div>
|
<div class="divider"></div>
|
||||||
<div class="item context js-aria-clickable report-comment" data-target="{{.item.HashTag}}-raw" data-modal="#report-comment-modal" data-repo-url="{{.ctxData.RepoLink}}" data-comment-id="{{.item.ID}}">{{ctx.Locale.Tr "moderation.report_abuse"}}</div>
|
<a class="item context" href="/-/abuse_reports/new?type={{$contentType}}&id={{.item.ID}}">{{ctx.Locale.Tr "moderation.report_content"}}</a>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
<div class="ui small modal" id="report-comment-modal">
|
|
||||||
<div class="header">
|
|
||||||
{{ctx.Locale.Tr "moderation.report_comment"}}
|
|
||||||
</div>
|
|
||||||
<div class="content">
|
|
||||||
<form class="ui form" id="report-comment-form" action="" method="post">
|
|
||||||
{{.CsrfTokenHtml}}
|
|
||||||
<input type="hidden" name="comment-id" />
|
|
||||||
<div class="inline required field">
|
|
||||||
<label><strong>{{ctx.Locale.Tr "moderation.report_remarks"}}</strong></label>
|
|
||||||
<textarea name="remarks"></textarea>
|
|
||||||
</div>
|
|
||||||
<div class="text right">
|
|
||||||
<button class="ui primary button">{{ctx.Locale.Tr "moderation.report_comment"}}</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
|
@ -124,9 +124,7 @@
|
||||||
{{end}}
|
{{end}}
|
||||||
</li>
|
</li>
|
||||||
<li class="block" hx-target="#profile-avatar-card" hx-indicator="#profile-avatar-card">
|
<li class="block" hx-target="#profile-avatar-card" hx-indicator="#profile-avatar-card">
|
||||||
<button type="submit" {{if $.IsReported}} disabled {{end}} class="ui basic orange button" data-modal-id="report-user" hx-post="{{.ContextUser.HomeLink}}?action=report" hx-confirm="-">
|
<a {{if $.IsReported}}disabled {{end}}class="ui basic orange button" href="/-/abuse_reports/new?type=user&id={{.ContextUser.ID}}">{{ctx.Locale.Tr "moderation.report_abuse"}}</a>
|
||||||
{{svg "octicon-blocked"}} {{ctx.Locale.Tr "moderation.report"}}
|
|
||||||
</button>
|
|
||||||
</li>
|
</li>
|
||||||
{{end}}
|
{{end}}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -77,14 +77,4 @@
|
||||||
{{template "base/modal_actions_confirm" .}}
|
{{template "base/modal_actions_confirm" .}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="ui g-modal-confirm delete modal" id="report-user">
|
|
||||||
<div class="header">
|
|
||||||
{{ctx.Locale.Tr "moderation.report_user"}}
|
|
||||||
</div>
|
|
||||||
<div class="content">
|
|
||||||
<p>{{ctx.Locale.Tr "moderation.report_user.detail"}}</p>
|
|
||||||
</div>
|
|
||||||
{{template "base/modal_actions_confirm" .}}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{{template "base/footer" .}}
|
{{template "base/footer" .}}
|
||||||
|
|
|
@ -599,21 +599,6 @@ export function initRepoIssueReferenceIssue() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function initRepoIssueReportComment() {
|
|
||||||
// Report abusive comment
|
|
||||||
$(document).on('click', '.report-comment', function (event) {
|
|
||||||
const $this = $(this);
|
|
||||||
const repo_url = $this.data('repo-url');
|
|
||||||
const comment_id = $this.data('comment-id');
|
|
||||||
const $modal = $($this.data('modal'));
|
|
||||||
$modal.find('#report-comment-form').attr('action',`${repo_url}/comments/${comment_id}/report`);
|
|
||||||
$modal.find('input[name="comment-id"]').val(`${comment_id}`);
|
|
||||||
$modal.modal('show');
|
|
||||||
|
|
||||||
event.preventDefault();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export function initRepoIssueWipToggle() {
|
export function initRepoIssueWipToggle() {
|
||||||
// Toggle WIP
|
// Toggle WIP
|
||||||
$('.toggle-wip a, .toggle-wip button').on('click', async (e) => {
|
$('.toggle-wip a, .toggle-wip button').on('click', async (e) => {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import {
|
import {
|
||||||
initRepoIssueBranchSelect, initRepoIssueCodeCommentCancel, initRepoIssueCommentDelete,
|
initRepoIssueBranchSelect, initRepoIssueCodeCommentCancel, initRepoIssueCommentDelete,
|
||||||
initRepoIssueComments, initRepoIssueDependencyDelete, initRepoIssueReferenceIssue, initRepoIssueReportComment,
|
initRepoIssueComments, initRepoIssueDependencyDelete, initRepoIssueReferenceIssue,
|
||||||
initRepoIssueTitleEdit, initRepoIssueWipToggle,
|
initRepoIssueTitleEdit, initRepoIssueWipToggle,
|
||||||
initRepoPullRequestUpdate, updateIssuesMeta, handleReply, initIssueTemplateCommentEditors, initSingleCommentEditor,
|
initRepoPullRequestUpdate, updateIssuesMeta, handleReply, initIssueTemplateCommentEditors, initSingleCommentEditor,
|
||||||
initRepoIssueAssignMe, reloadConfirmDraftComment,
|
initRepoIssueAssignMe, reloadConfirmDraftComment,
|
||||||
|
@ -561,7 +561,6 @@ export function initRepository() {
|
||||||
|
|
||||||
initRepoDiffConversationNav();
|
initRepoDiffConversationNav();
|
||||||
initRepoIssueReferenceIssue();
|
initRepoIssueReferenceIssue();
|
||||||
initRepoIssueReportComment();
|
|
||||||
|
|
||||||
initRepoIssueCommentDelete();
|
initRepoIssueCommentDelete();
|
||||||
initRepoIssueDependencyDelete();
|
initRepoIssueDependencyDelete();
|
||||||
|
|
Loading…
Reference in a new issue