Admin labels on photos surrounding explicit flags
* Add 'admin labels' to photos so an admin can classify a photo as: * Not Explicit: e.g. it was flagged by the community but does not actually need to be explicit. This option will hide the prompt to report the explicit photo again. * Force Explicit: if a user is fighting an explicit flag and keeps removing it from their photo, the photo can be force marked explicit. * Admin labels appear on the Permalink page and in the edit photo settings when viewed as a photo moderator admin.
This commit is contained in:
parent
542d0bb300
commit
295183559d
37
pkg/config/admin_labels.go
Normal file
37
pkg/config/admin_labels.go
Normal file
|
@ -0,0 +1,37 @@
|
|||
package config
|
||||
|
||||
import "strings"
|
||||
|
||||
// Admin Labels.
|
||||
const (
|
||||
// Admin Labels for Photos
|
||||
AdminLabelPhotoNonExplicit = "non-explicit"
|
||||
AdminLabelPhotoForceExplicit = "force-explicit"
|
||||
)
|
||||
|
||||
var (
|
||||
AdminLabelPhotoOptions = []ChecklistOption{
|
||||
{
|
||||
Value: AdminLabelPhotoNonExplicit,
|
||||
Label: "This is not an Explicit photo",
|
||||
Help: "Hide the prompt 'Should this photo be marked as explicit?' as this photo does not NEED to be Explicit. " +
|
||||
"Note: the owner of this photo MAY still mark it explicit if they want to.",
|
||||
},
|
||||
{
|
||||
Value: AdminLabelPhotoForceExplicit,
|
||||
Label: "Force this photo to be marked as Explicit",
|
||||
Help: "Enabling this option will force the Explicit tag to stay on, and not allow the user to remove it.",
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
// HasAdminLabel checks if a comma-separated set of admin labels contains the label.
|
||||
func HasAdminLabel(needle string, haystack string) bool {
|
||||
labels := strings.Split(haystack, ",")
|
||||
for _, label := range labels {
|
||||
if strings.TrimSpace(label) == needle {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
|
@ -111,6 +111,24 @@ func Edit() http.HandlerFunc {
|
|||
models.NewFieldDiff("Visibility", photo.Visibility, visibility),
|
||||
}
|
||||
|
||||
// Admin label options.
|
||||
if requestUser.HasAdminScope(config.ScopePhotoModerator) {
|
||||
var adminLabel string
|
||||
if labels, ok := r.PostForm["admin_label"]; ok {
|
||||
adminLabel = strings.Join(labels, ",")
|
||||
}
|
||||
diffs = append(diffs,
|
||||
models.NewFieldDiff("Admin Label", photo.AdminLabel, adminLabel),
|
||||
)
|
||||
|
||||
photo.AdminLabel = adminLabel
|
||||
}
|
||||
|
||||
// Admin label: forced explicit?
|
||||
if photo.HasAdminLabelForceExplicit() {
|
||||
isExplicit = true
|
||||
}
|
||||
|
||||
photo.Caption = caption
|
||||
photo.AltText = altText
|
||||
photo.Explicit = isExplicit
|
||||
|
@ -167,6 +185,9 @@ func Edit() http.HandlerFunc {
|
|||
|
||||
// Allow this change but clear the Flagged status.
|
||||
photo.Flagged = false
|
||||
|
||||
// Clear the notification about this.
|
||||
models.RemoveSpecificNotification(currentUser.ID, models.NotificationExplicitPhoto, "photos", photo.ID)
|
||||
}
|
||||
|
||||
if err := photo.Save(); err != nil {
|
||||
|
@ -211,6 +232,10 @@ func Edit() http.HandlerFunc {
|
|||
"EditPhoto": photo,
|
||||
"SiteGalleryThrottled": SiteGalleryThrottled,
|
||||
"SiteGalleryThrottleLimit": config.SiteGalleryRateLimitMax,
|
||||
|
||||
// Available admin labels enum.
|
||||
"RequestUser": requestUser,
|
||||
"AvailableAdminLabels": config.AdminLabelPhotoOptions,
|
||||
}
|
||||
|
||||
if err := tmpl.Execute(w, r, vars); err != nil {
|
||||
|
|
|
@ -22,6 +22,7 @@ type Photo struct {
|
|||
Caption string
|
||||
AltText string
|
||||
Flagged bool // photo has been reported by the community
|
||||
AdminLabel string // admin label(s) on this photo (e.g. verified non-explicit)
|
||||
Visibility PhotoVisibility `gorm:"index"`
|
||||
Gallery bool `gorm:"index"` // photo appears in the public gallery (if public)
|
||||
Explicit bool `gorm:"index"` // is an explicit photo
|
||||
|
@ -274,6 +275,21 @@ func GetOrphanedPhotos() ([]*Photo, int64, error) {
|
|||
return ps, count, res.Error
|
||||
}
|
||||
|
||||
// HasAdminLabelNonExplicit checks if the non-explicit admin label is applied to this photo.
|
||||
func (p *Photo) HasAdminLabelNonExplicit() bool {
|
||||
return config.HasAdminLabel(config.AdminLabelPhotoNonExplicit, p.AdminLabel)
|
||||
}
|
||||
|
||||
// HasAdminLabelForceExplicit checks if the force-explicit admin label is applied to this photo.
|
||||
func (p *Photo) HasAdminLabelForceExplicit() bool {
|
||||
return config.HasAdminLabel(config.AdminLabelPhotoForceExplicit, p.AdminLabel)
|
||||
}
|
||||
|
||||
// HasAdminLabel checks if the photo has an admin label (for convenient front-end access on the Edit page).
|
||||
func (p *Photo) HasAdminLabel(label string) bool {
|
||||
return config.HasAdminLabel(label, p.AdminLabel)
|
||||
}
|
||||
|
||||
// PhotoMap helps map a set of users to look up by ID.
|
||||
type PhotoMap map[uint64]*Photo
|
||||
|
||||
|
|
|
@ -239,6 +239,11 @@
|
|||
class="blurred-explicit">
|
||||
</a>
|
||||
</div>
|
||||
<div class="mt-3 has-text-smaller">
|
||||
<a href="/photo/edit?id={{.TableID}}">
|
||||
<i class="fa fa-edit mr-1"></i> Edit this photo
|
||||
</a>
|
||||
</div>
|
||||
{{end}}
|
||||
{{end}}
|
||||
</div>
|
||||
|
|
|
@ -568,7 +568,7 @@
|
|||
{{template "card-body" .}}
|
||||
|
||||
<!-- Quick mark photo as explicit -->
|
||||
{{if and (not .Explicit) (ne .UserID $Root.CurrentUser.ID)}}
|
||||
{{if and (not .Explicit) (ne .UserID $Root.CurrentUser.ID) (not .HasAdminLabelNonExplicit)}}
|
||||
<div class="mt-2">
|
||||
<a href="#"
|
||||
class="has-text-danger is-size-7 nonshy-mark-explicit"
|
||||
|
@ -694,7 +694,7 @@
|
|||
{{template "card-body" .}}
|
||||
|
||||
<!-- Quick mark photo as explicit -->
|
||||
{{if and (not .Explicit) (ne .UserID $Root.CurrentUser.ID)}}
|
||||
{{if and (not .Explicit) (ne .UserID $Root.CurrentUser.ID) (not .HasAdminLabelNonExplicit)}}
|
||||
<div class="mt-2">
|
||||
<a href="#"
|
||||
class="has-text-danger is-size-7 nonshy-mark-explicit"
|
||||
|
|
|
@ -109,8 +109,18 @@
|
|||
<small class="has-text-grey">Uploaded {{.Photo.CreatedAt.Format "Jan _2 2006 15:04:05"}}</small>
|
||||
</div>
|
||||
|
||||
<!-- Show admin labels to admins -->
|
||||
{{if .CurrentUser.HasAdminScope "social.moderator.photo"}}
|
||||
{{if .Photo.AdminLabel}}
|
||||
<div class="mt-2">
|
||||
<i class="fa fa-peace has-text-danger mr-1"></i>
|
||||
Admin Label: {{.Photo.AdminLabel}}
|
||||
</div>
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
||||
<!-- Quick mark photo as explicit -->
|
||||
{{if and (not .Photo.Explicit) (ne .Photo.UserID .CurrentUser.ID)}}
|
||||
{{if and (not .Photo.Explicit) (ne .Photo.UserID .CurrentUser.ID) (not .Photo.HasAdminLabelNonExplicit)}}
|
||||
<div class="mt-1">
|
||||
<a href="#"
|
||||
class="has-text-danger is-size-7 nonshy-mark-explicit"
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
</div>
|
||||
</section>
|
||||
|
||||
{{ $Root := . }}
|
||||
{{ $User := .CurrentUser }}
|
||||
|
||||
<!-- Drag/Drop Modal -->
|
||||
|
@ -438,7 +439,8 @@
|
|||
<input type="checkbox"
|
||||
name="explicit"
|
||||
value="true"
|
||||
{{if .EditPhoto.Explicit}}checked{{end}}>
|
||||
{{if .EditPhoto.Explicit}}checked{{end}}
|
||||
{{if .EditPhoto.HasAdminLabelForceExplicit}}disabled{{end}}>
|
||||
{{if $IsFlagged}}<del class="cursor-not-allowed">{{end}}
|
||||
This photo contains explicit content
|
||||
{{if $IsFlagged}}</del>{{end}}
|
||||
|
@ -488,6 +490,44 @@
|
|||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Admin Labels -->
|
||||
{{if and .EditPhoto (.RequestUser.HasAdminScope "social.moderator.photo")}}
|
||||
<hr>
|
||||
<div class="field">
|
||||
<label class="label has-text-danger">
|
||||
<span>Admin Labels</span>
|
||||
<span class="icon"><i class="fa fa-peace"></i></span>
|
||||
</label>
|
||||
|
||||
<p class="help">
|
||||
The options below can apply moderation rules to this picture, especially regarding
|
||||
its 'explicit' status. For example: if a community member flagged this picture as
|
||||
explicit, but it does NOT need to be marked as such, select that label below: and
|
||||
the website will no longer allow this photo to be flagged as explicit again.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{{range .AvailableAdminLabels}}
|
||||
<div class="field">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox"
|
||||
name="admin_label"
|
||||
value="{{.Value}}"
|
||||
{{if ($Root.EditPhoto.HasAdminLabel .Value)}}checked{{end}}>
|
||||
{{.Label}}
|
||||
</label>
|
||||
<p class="help">
|
||||
{{.Help}}
|
||||
</p>
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
<p class="help">
|
||||
<strong>Reminder:</strong> click on 'Save Changes' to apply these labels!
|
||||
</p>
|
||||
|
||||
{{end}}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user