Enable users to report without sending a mail
This commit is contained in:
parent
f9c33e2cad
commit
2ad0c8dbc7
5 changed files with 119 additions and 6 deletions
|
|
@ -9,6 +9,8 @@ class lgAdmin {
|
|||
this.core = instance;
|
||||
this.$LG = $LG;
|
||||
this.isStaff = instance.settings.isStaff;
|
||||
this.csrfToken = instance.settings.csrfToken;
|
||||
this.photoId = 0;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
@ -18,24 +20,78 @@ class lgAdmin {
|
|||
const reportIcon = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" fill=\"currentColor\" viewBox=\"0 0 16 16\"><path d=\"M11.46.146A.5.5 0 0 0 11.107 0H4.893a.5.5 0 0 0-.353.146L.146 4.54A.5.5 0 0 0 0 4.893v6.214a.5.5 0 0 0 .146.353l4.394 4.394a.5.5 0 0 0 .353.146h6.214a.5.5 0 0 0 .353-.146l4.394-4.394a.5.5 0 0 0 .146-.353V4.893a.5.5 0 0 0-.146-.353L11.46.146zM8 4c.535 0 .954.462.9.995l-.35 3.507a.552.552 0 0 1-1.1 0L7.1 4.995A.905.905 0 0 1 8 4zm.002 6a1 1 0 1 1 0 2 1 1 0 0 1 0-2z\"/></svg>";
|
||||
|
||||
// Add button linking to Django admin page
|
||||
this.core.$toolbar.append(`<a href="#" id="lg-admin" title="Go to admin" class="lg-icon lg-bi-icon">${adminIcon}</a>`);
|
||||
this.core.$toolbar.append(`<a href="#" target="_blank" id="lg-admin" title="Go to admin" class="lg-icon lg-bi-icon">${adminIcon}</a>`);
|
||||
document.getElementById("lg-admin").style.display = this.isStaff ? 'block' : 'none';
|
||||
|
||||
// Add button to delete photo
|
||||
this.core.$toolbar.append(`<a href="#" id="lg-delete" title="Remove this photo" class="lg-icon lg-bi-icon">${deleteIcon}</a>`);
|
||||
document.getElementById("lg-delete").style.display = this.isStaff ? 'block' : 'none';
|
||||
document.getElementById("lg-delete").addEventListener('click', this.onDelete.bind(this));
|
||||
|
||||
// Add button to report photo
|
||||
this.core.$toolbar.append(`<a href="#" id="lg-report" title="Notify abuse" class="lg-icon lg-bi-icon">${reportIcon}</a>`);
|
||||
document.getElementById("lg-report").addEventListener('click', this.onReport.bind(this));
|
||||
|
||||
this.core.LGel.on("lgAfterSlide.admin", this.onAfterSlide.bind(this));
|
||||
}
|
||||
|
||||
// Event called when showing a new slide
|
||||
onAfterSlide(event) {
|
||||
const photoId = this.core.galleryItems[event.detail.index].slideName;
|
||||
document.getElementById("lg-admin").href = `https://photos.crans.org/admin/photologue/photo/${photoId}/change/`;
|
||||
document.getElementById("lg-delete").href = `https://photos.crans.org/admin/photologue/photo/${photoId}/delete/`;
|
||||
document.getElementById("lg-report").href = `mailto:photos@crans.org?subject=[ABUS] Photo ${photoId}&body=${encodeURIComponent(window.location.href)}`;
|
||||
this.photoId = this.core.galleryItems[event.detail.index].slideName;
|
||||
document.getElementById("lg-admin").href = `/admin/photologue/photo/${this.photoId}/change/`;
|
||||
}
|
||||
|
||||
// Event called when user click on delete button
|
||||
onDelete(event) {
|
||||
event.preventDefault();
|
||||
if(confirm("Are you sure to delete this photo?")) {
|
||||
// Build form request
|
||||
let data = new FormData();
|
||||
data.append('csrfmiddlewaretoken', this.csrfToken);
|
||||
fetch(`/photo/${this.photoId}/delete/`, {
|
||||
method: "POST",
|
||||
body: data,
|
||||
credentials: 'same-origin',
|
||||
}).then(res => {
|
||||
if(res.ok) {
|
||||
console.log("Deletion complete, response:", res);
|
||||
|
||||
// Remove HTML element
|
||||
document.querySelectorAll(`[data-slide-name='${this.photoId}']`)[0].remove()
|
||||
this.core.goToNextSlide();
|
||||
this.core.refresh();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Event called when user click on report button
|
||||
onReport(event) {
|
||||
event.preventDefault();
|
||||
if(confirm("Are you sure to report this photo?")) {
|
||||
// Build form request
|
||||
let data = new FormData();
|
||||
data.append('csrfmiddlewaretoken', this.csrfToken);
|
||||
fetch(`/photo/${this.photoId}/report/`, {
|
||||
method: "POST",
|
||||
body: data,
|
||||
credentials: 'same-origin',
|
||||
}).then(res => {
|
||||
if(res.ok) {
|
||||
console.log("Report complete, response:", res);
|
||||
|
||||
// Update HTML element
|
||||
const thumbnail = document.querySelectorAll(`[data-slide-name='${this.photoId}']`)[0];
|
||||
if (!this.isStaff) {
|
||||
thumbnail.remove()
|
||||
this.core.goToNextSlide();
|
||||
this.core.refresh();
|
||||
} else {
|
||||
location.reload();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Plugins must have destroy prototype
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
|||
plugins: [lgAdmin, lgHash, lgThumbnail, lgZoom],
|
||||
customSlideName: true,
|
||||
isStaff: {{ request.user.is_staff|yesno:"true,false" }},
|
||||
csrfToken: "{{ csrf_token }}",
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
|
|
|||
24
photologue/templates/photologue/photo_confirm_report.html
Normal file
24
photologue/templates/photologue/photo_confirm_report.html
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
{% extends "base.html" %}
|
||||
{% comment %}
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
{% endcomment %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}{% trans "Report confirmation" %}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<h1>{% trans "Report confirmation" %}</h1>
|
||||
<form method="post">{% csrf_token %}
|
||||
<p>
|
||||
{% blocktranslate trimmed %}
|
||||
Are you sure you want to report <code>{{ object }}</code>?
|
||||
This photo will no longer be public, and administrators will be notified.
|
||||
{% endblocktranslate %}
|
||||
</p>
|
||||
<input type="submit" class="btn btn-warning" value="{% trans "Confirm" %}">
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
@ -2,7 +2,7 @@ from django.urls import path, re_path
|
|||
|
||||
from .views import (GalleryDetailView, GalleryArchiveIndexView,
|
||||
GalleryDownload, GalleryUpload, GalleryYearArchiveView,
|
||||
PhotoDetailView, PhotoDeleteView, TagDetail)
|
||||
PhotoDetailView, PhotoDeleteView, PhotoReportView, TagDetail)
|
||||
|
||||
app_name = 'photologue'
|
||||
urlpatterns = [
|
||||
|
|
@ -14,5 +14,6 @@ urlpatterns = [
|
|||
path('gallery/<slug:slug>/download/', GalleryDownload.as_view(), name='pl-gallery-download'),
|
||||
path('photo/<int:pk>/', PhotoDetailView.as_view(), name='pl-photo'),
|
||||
path('photo/<int:pk>/delete/', PhotoDeleteView.as_view(), name='pl-photo-delete'),
|
||||
path('photo/<int:pk>/report/', PhotoReportView.as_view(), name='pl-photo-report'),
|
||||
path('upload/', GalleryUpload.as_view(), name='pl-gallery-upload'),
|
||||
]
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ from django.views.generic.dates import ArchiveIndexView, YearArchiveView
|
|||
from django.views.generic.detail import DetailView
|
||||
from django.views.generic.edit import FormView, DeleteView
|
||||
from PIL import Image
|
||||
from django.shortcuts import redirect
|
||||
|
||||
from .forms import UploadForm
|
||||
from .models import Gallery, Photo, Tag
|
||||
|
|
@ -68,6 +69,36 @@ class PhotoDeleteView(PermissionRequiredMixin, DeleteView):
|
|||
return reverse_lazy('photologue:pl-gallery', args=[slug])
|
||||
|
||||
|
||||
class PhotoReportView(LoginRequiredMixin, DetailView):
|
||||
model = Photo
|
||||
template_name = 'photologue/photo_confirm_report.html'
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
"""
|
||||
Make photo private on POST.
|
||||
"""
|
||||
# Mark photo as private
|
||||
photo = self.get_object()
|
||||
photo.is_public = False
|
||||
photo.save()
|
||||
|
||||
# Get gallery
|
||||
galleries = photo.galleries.all()
|
||||
gallery_slug = galleries[0].slug if galleries else ''
|
||||
if not gallery_slug:
|
||||
url = reverse_lazy('photologue:pl-gallery-archive')
|
||||
url = reverse_lazy('photologue:pl-gallery', args=[gallery_slug])
|
||||
|
||||
# Send mail to managers
|
||||
mail_managers(
|
||||
subject=f"Abuse report for photo id {photo.pk}",
|
||||
message=f"{self.request.user.username} reported an abuse for `{photo.title}`: {url}#lg=1&slide={photo.pk}",
|
||||
)
|
||||
|
||||
# Redirect to gallery
|
||||
return redirect(url)
|
||||
|
||||
|
||||
class TagDetail(LoginRequiredMixin, DetailView):
|
||||
model = Tag
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue