/* * Custom LightGallery plugin to add some buttons for administration * * This file is part of photo21 * Copyright (C) 2022 Amicale des élèves de l'ENS Paris-Saclay * SPDX-License-Identifier: GPL-3.0-or-later */ class lgAdmin { constructor(instance, $LG) { this.core = instance; this.$LG = $LG; this.isStaff = document.querySelector('[name=is_staff]').value === "true"; this.userId = document.querySelector('[name=user_id]').value; this.csrfToken = document.querySelector('[name=csrfmiddlewaretoken]').value; this.photoId = 0; return this; } init() { const adminIcon = ""; const deleteIcon = "";; const reportIcon = ""; // Add button linking to Django admin page this.core.$toolbar.append(`${adminIcon}`); document.getElementById("lg-admin").style.display = this.isStaff ? 'block' : 'none'; // Add button to delete photo this.core.$toolbar.append(`${deleteIcon}`); document.getElementById("lg-delete").style.display = 'none'; document.getElementById("lg-delete").addEventListener('click', this.onDelete.bind(this)); // Add button to report photo this.core.$toolbar.append(`${reportIcon}`); 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) { this.photoId = this.core.galleryItems[event.detail.index].slideName; document.getElementById("lg-admin").href = `/admin/photologue/photo/${this.photoId}/change/`; const el = document.querySelector(`[data-slide-name='${this.photoId}']`); const ownerId = el ? el.dataset.ownerId : null; const canDelete = this.isStaff || (ownerId && ownerId === this.userId); document.getElementById("lg-delete").style.display = canDelete ? 'block' : 'none'; } // Navigate away from a photo that was just deleted/hidden. // We slide first (while the item still exists), then remove and reindex after the // animation so lightgallery's internal index/counter stays consistent. _navigateAfterRemove(photoId, currentIndex) { const total = this.core.galleryItems.length; if (total <= 1) { const el = document.querySelector(`[data-slide-name='${photoId}']`); if (el) el.remove(); this.core.refresh(); this.core.closeGallery(); return; } const goingForward = currentIndex < total - 1; const targetIndex = goingForward ? currentIndex + 1 : currentIndex - 1; this.core.LGel.on('lgAfterSlide.adminRemove', () => { this.core.LGel.off('lgAfterSlide.adminRemove'); const thumb = document.querySelector(`[data-slide-name='${photoId}']`); if (thumb) thumb.remove(); const lgId = this.core.lgId; const deletedItem = document.getElementById(`lg-item-${lgId}-${currentIndex}`); if (deletedItem) deletedItem.remove(); document.querySelectorAll(`[id^="lg-item-${lgId}-"]`).forEach(item => { const idx = parseInt(item.id.split('-').pop(), 10); if (idx > currentIndex) item.id = `lg-item-${lgId}-${idx - 1}`; }); this.core.refresh(); if (goingForward) { this.core.index = currentIndex; this.core.updateCurrentCounter(currentIndex); } }); this.core.slide(targetIndex, false, false, false); } // Event called when user click on delete button onDelete(event) { event.preventDefault(); if(confirm("Are you sure to delete this photo?")) { // Build form request const photoId = this.photoId; const currentIndex = this.core.index; let data = new FormData(); data.append('csrfmiddlewaretoken', this.csrfToken); fetch(`/photo/${photoId}/delete/`, { method: "POST", redirect: "manual", // do not load gallery again body: data, credentials: 'same-origin', }).then(() => this._navigateAfterRemove(photoId, currentIndex)); } } // Event called when user click on report button onReport(event) { event.preventDefault(); if(confirm("Are you sure to report this photo?")) { // Build form request const photoId = this.photoId; const currentIndex = this.core.index; let data = new FormData(); data.append('csrfmiddlewaretoken', this.csrfToken); fetch(`/photo/${photoId}/report/`, { method: "POST", redirect: "manual", // do not load gallery again body: data, credentials: 'same-origin', }).then(() => { const thumbnail = document.querySelector(`[data-slide-name='${photoId}']`); if (!this.isStaff) { this._navigateAfterRemove(photoId, currentIndex); } else { location.reload(); } }); } } // Plugins must have destroy prototype destroy() { } }