Files
Wordpress-MC-Gallery/assets/js/gallery-pro.js
2026-04-03 01:31:36 +02:00

804 lines
33 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
(function ($) {
'use strict';
if (typeof mcGalleryPro === 'undefined') {
console.error('MC Gallery Pro: Configuration not found.');
return;
}
const api = mcGalleryPro.restBase.replace(/\/?$/, '');
const ajaxUrl = mcGalleryPro.uploadUrl;
const maxUploads = mcGalleryPro.maxUploads || 5;
let originalBodyPadding = '';
let scrollbarWidth = 0;
let sessionData = {
token: null,
username: null,
serverId: null,
verified: false
};
let selectedFiles = [];
function getScrollbarWidth() {
if (scrollbarWidth > 0) return scrollbarWidth;
const outer = document.createElement('div');
outer.style.visibility = 'hidden';
outer.style.width = '100px';
outer.style.msOverflowStyle = 'scrollbar';
document.body.appendChild(outer);
const widthNoScroll = outer.offsetWidth;
outer.style.overflow = 'scroll';
const inner = document.createElement('div');
inner.style.width = '100%';
outer.appendChild(inner);
const widthWithScroll = inner.offsetWidth;
outer.parentNode.removeChild(outer);
scrollbarWidth = widthNoScroll - widthWithScroll;
return scrollbarWidth;
}
function showFeedback(msg, type = 'info') {
const $fb = $('#mc-feedback-msg');
$fb.removeClass('mc-msg-success mc-msg-error');
if (type === 'success') {
$fb.addClass('mc-msg-success');
} else if (type === 'error') {
$fb.addClass('mc-msg-error');
}
$fb.html(msg).fadeIn(300);
}
function switchStep(stepNum) {
$('.mc-step').removeClass('active');
$(`.mc-step[data-step="${stepNum}"]`).addClass('active');
}
function resetModal() {
$('#mc-upload-username').val('');
$('#mc-token-text').text('Waiting...');
$('#mc-upload-file').val('');
$('#mc-file-name').text('Keine Bilder gewählt').css('color', '');
$('.mc-file-drop').css('border-color', '').css('background', '');
$('#mc-feedback-msg').hide().empty();
$('#mc-file-preview').empty();
$('#mc-upload-progress').hide();
$('#mc-btn-upload-more').hide();
$('#mc-btn-final-upload').show();
selectedFiles = [];
sessionData = {
token: null,
username: null,
serverId: null,
verified: false
};
switchStep(1);
}
function loadServers() {
const $select = $('#mc-upload-server');
if (!$select.length) return;
$select.html('<option>Lade Server...</option>').prop('disabled', true);
fetch(api + '/servers')
.then(response => {
if (!response.ok) throw new Error('Server response not OK');
return response.json();
})
.then(data => {
if (data.success && Array.isArray(data.data) && data.data.length > 0) {
$select.empty().prop('disabled', false);
data.data.forEach(server => {
const displayText = server.host
? `${server.title} (${server.host})`
: server.title;
$select.append($('<option>')
.val(server.id)
.text(displayText)
);
});
} else {
$select.html('<option>Keine aktiven Server</option>');
}
})
.catch(error => {
console.error('Failed to load servers:', error);
$select.html('<option>Fehler beim Laden</option>');
});
}
function loadAlbums() {
const $select = $('#mc-upload-album');
$select.html('<option value="">Kein Album</option>').prop('disabled', true);
// Auch ohne Token laden, wenn Forum-Session aktiv
if ((!sessionData.token && !sessionData.verified) || !sessionData.username) return;
fetch(api + '/albums', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
token: sessionData.token || '',
username: sessionData.username,
server_id: sessionData.serverId || ''
})
})
.then(response => response.json())
.then(data => {
if (data.success && data.data.albums) {
$select.prop('disabled', false);
data.data.albums.forEach(album => {
$select.append($('<option>')
.val(album.id)
.text(album.title)
);
});
}
})
.catch(error => {
console.error('Failed to load albums:', error);
});
}
// FIX 1: View Counter Zähler erhöhen
function incrementViewCount(attachId, $badgeElement) {
$.post(ajaxUrl, {
action: 'mc_gallery_increment_view',
attach_id: attachId,
nonce: mcGalleryPro.nonce
}, function(response) {
if (response.success && response.data && typeof response.data.views !== 'undefined') {
// Badge sofort aktualisieren (Animation optional)
$badgeElement.find('.mc-views-count').text(response.data.views);
}
}).fail(function() {
console.error('Failed to increment view count');
});
}
function renderFilePreview() {
const $preview = $('#mc-file-preview');
$preview.empty();
if (selectedFiles.length === 0) return;
selectedFiles.forEach((file, index) => {
const reader = new FileReader();
reader.onload = function(e) {
const $item = $(`
<div class="mc-preview-item" data-index="${index}">
<img src="${e.target.result}" alt="${file.name}">
<button class="mc-preview-remove" data-index="${index}" title="Entfernen">×</button>
<span class="mc-preview-name">${file.name}</span>
</div>
`);
$preview.append($item);
};
reader.readAsDataURL(file);
});
updateFileCount();
}
function updateFileCount() {
const count = selectedFiles.length;
$('#mc-file-name').css('color', '').removeClass('mc-msg-error-text');
$('#mc-btn-final-upload').prop('disabled', false).removeClass('mc-btn-disabled');
$('.mc-file-drop').css({
'border-color': '',
'background': ''
});
if (count === 0) {
$('#mc-file-name').text('Keine Bilder gewählt');
} else if (count > maxUploads) {
$('#mc-file-name')
.html(`<strong>${count} / ${maxUploads} Bilder</strong> (Zu viele!)`)
.css('color', 'var(--mc-error)')
.addClass('mc-msg-error-text');
$('#mc-btn-final-upload')
.prop('disabled', true)
.addClass('mc-btn-disabled');
$('.mc-file-drop').css({
'border-color': 'var(--mc-error)',
'background': 'rgba(239, 68, 68, 0.05)'
});
} else {
$('#mc-file-name')
.html(`<strong>${count} Bild${count > 1 ? 'er' : ''}</strong> ausgewählt`)
.css('color', 'var(--mc-text-main)');
$('.mc-file-drop').css({
'border-color': 'var(--mc-primary)',
'background': 'rgba(16, 185, 129, 0.05)'
});
}
$('#mc-upload-btn-text').text(count > 0 ? `${count} Bild${count > 1 ? 'er' : ''} hochladen` : 'Bilder hochladen');
}
function openModal() {
$('#mc-upload-modal').addClass('open').attr('aria-hidden', 'false');
originalBodyPadding = $('body').css('padding-right');
const width = getScrollbarWidth();
$('html').css('overflow', 'hidden');
$('body').css('padding-right', (parseInt(originalBodyPadding) || 0) + width + 'px');
resetModal();
loadServers();
// Wenn User bereits forum-verifiziert ist: direkt zu Schritt 3 springen
if (mcGalleryPro.forumVerified) {
const fv = mcGalleryPro.forumVerified;
sessionData.verified = true;
sessionData.username = fv.mc_username;
sessionData.serverId = fv.server_id;
sessionData.token = null;
$('#mc-session-user').text(fv.display_name || fv.mc_username);
$('#mc_form_username').val(fv.mc_username);
$('#mc_form_server').val(fv.server_id);
$('#mc_form_token').val('');
switchStep(3);
loadAlbums();
}
}
function closeModal() {
$('#mc-upload-modal').removeClass('open').attr('aria-hidden', 'true');
$('html').css('overflow', '');
$('body').css('padding-right', originalBodyPadding);
setTimeout(resetModal, 300);
}
// Forum-Login: Auf globales Event reagieren
$(document).on('mc_gallery_forum_verified', function(e, data) {
var fallbackServerId = $('#mc-upload-server').val() || '';
if (data && !data.server_id) {
data.server_id = fallbackServerId;
}
if (!data || !data.mc_username || !data.server_id) {
showFeedback('Forum-Login: Ungültige Antwort vom Server.', 'error');
return;
}
sessionData.verified = true;
sessionData.username = data.mc_username;
sessionData.serverId = data.server_id;
sessionData.token = null; // Kein Token nötig
$('#mc-session-user').text(data.display_name || data.mc_username);
$('#mc_form_username').val(data.mc_username);
$('#mc_form_server').val(data.server_id);
$('#mc_form_token').val('');
showFeedback('✓ Erfolgreich mit Forum-Login verifiziert!', 'success');
setTimeout(() => {
switchStep(3);
console.log('[MC-Gallery] mc_gallery_forum_verified: switchStep(3) ausgeführt, Upload-Schritt sollte sichtbar sein.');
loadAlbums();
}, 800);
});
$(document).ready(function () {
loadServers();
$('#mc-open-upload-modal').on('click', function(e) {
e.preventDefault();
openModal();
});
$('.mc-modal-close, .mc-modal-backdrop').on('click', function() {
closeModal();
});
$(document).on('keydown', function(e) {
if (e.key === 'Escape' && $('#mc-upload-modal').hasClass('open')) {
closeModal();
}
});
// Forum-Login-Button im Modal (Schritt 1) — einmalig binden, NICHT inside btn-generate
$(document).on('click', '#mc-btn-forum-login', function () {
const serverId = $('#mc-upload-server').val();
if (!serverId || serverId === '') {
showFeedback('Bitte wähle einen Server aus.', 'error');
return;
}
const $btn = $(this);
const originalText = $btn.html();
$btn.prop('disabled', true).html('<span class="mc-loading"></span> Prüfe Forum-Login...');
$.ajax({
url: ajaxUrl,
method: 'POST',
dataType: 'json',
data: {
action: 'mc_forum_verify_upload',
nonce: mcGalleryPro.forumNonce || mcGalleryPro.nonce,
server_id: serverId
},
success: function (data) {
$btn.prop('disabled', false).html(originalText);
if (data.success && data.data && data.data.mc_username) {
if (!data.data.server_id) {
data.data.server_id = serverId || ($('#mc-upload-server').val() || '');
}
if (!data.data.server_id) {
showFeedback('Forum-Login erfolgreich, aber keine Server-ID gefunden. Bitte Server wählen und erneut versuchen.', 'error');
return;
}
sessionData.verified = true;
sessionData.username = data.data.mc_username;
sessionData.serverId = data.data.server_id;
sessionData.token = null;
$('#mc-session-user').text(data.data.display_name || data.data.mc_username);
$('#mc_form_username').val(data.data.mc_username);
$('#mc_form_server').val(data.data.server_id);
$('#mc_form_token').val('');
showFeedback('✓ Erfolgreich mit Forum-Login verifiziert!', 'success');
setTimeout(() => { switchStep(3); loadAlbums(); }, 800);
} else {
const msg = (data.data && data.data.message) ? data.data.message : (data.message || 'Verifizierung fehlgeschlagen.');
showFeedback(msg, 'error');
}
},
error: function () {
$btn.prop('disabled', false).html(originalText);
showFeedback('Netzwerkfehler bei der Forum-Login-Prüfung', 'error');
}
});
});
$('#mc-btn-generate').on('click', function () {
const username = $('#mc-upload-username').val().trim();
const serverId = $('#mc-upload-server').val();
if (!username) {
showFeedback('Bitte gib deinen Minecraft-Namen ein.', 'error');
$('#mc-upload-username').focus();
return;
}
if (!serverId || serverId === '') {
showFeedback('Bitte wähle einen Server aus.', 'error');
return;
}
const $btn = $(this);
const originalText = $btn.text();
$btn.prop('disabled', true).html('<span class="mc-loading"></span> Starte Session...');
fetch(api + '/request-token', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
username: username,
server_id: parseInt(serverId, 10)
})
})
.then(response => response.json())
.then(data => {
$btn.prop('disabled', false).text(originalText);
if (data.success && data.data && data.data.token) {
sessionData.token = data.data.token;
sessionData.username = username;
sessionData.serverId = parseInt(serverId, 10);
$('#mc-token-text').text(data.data.token);
$('#mc_form_token').val(data.data.token);
$('#mc_form_username').val(username);
$('#mc_form_server').val(serverId);
showFeedback('✓ Session-Token erstellt! Gültig für 1 Stunde.', 'success');
setTimeout(() => switchStep(2), 600);
} else {
showFeedback(data.message || 'Fehler beim Token-Erstellen', 'error');
}
})
.catch(error => {
console.error('Token generation error:', error);
$btn.prop('disabled', false).text(originalText);
showFeedback('Netzwerkfehler beim Token-Erstellen', 'error');
});
});
$('.mc-copy-btn').on('click', function() {
const text = $('#mc-token-text').text();
const $btn = $(this);
if (text === 'Waiting...' || !text) {
showFeedback('Kein Token zum Kopieren verfügbar', 'error');
return;
}
navigator.clipboard.writeText(text)
.then(() => {
const original = $btn.text();
$btn.text('✓');
setTimeout(() => $btn.text(original), 2000);
})
.catch(() => {
showFeedback('Kopieren fehlgeschlagen', 'error');
});
});
$('#mc-btn-check').on('click', function () {
const token = $('#mc_form_token').val();
if (!token) {
showFeedback('Kein Token vorhanden', 'error');
return;
}
const $btn = $(this);
const originalText = $btn.text();
$btn.prop('disabled', true).html('<span class="mc-loading"></span> Prüfe...');
fetch(api + '/check-token', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ token: token })
})
.then(response => response.json().then(data => {
if (!response.ok) throw new Error(data.message || 'Verifizierung fehlgeschlagen.');
return data;
}))
.then(data => {
$btn.prop('disabled', false).text(originalText);
if (data.success && data.data && data.data.claimed) {
sessionData.verified = true;
$('#mc-session-user').text(data.data.claimed_by);
showFeedback(`✓ Erfolgreich verifiziert als <strong>${data.data.claimed_by}</strong>!`, 'success');
setTimeout(() => {
switchStep(3);
loadAlbums();
}, 800);
} else {
sessionData.verified = false;
showFeedback('⚠ Noch nicht verifiziert. Gib <strong>/verify [Token]</strong> im Spiel ein.', 'error');
}
})
.catch(error => {
console.error('Check token error:', error);
$btn.prop('disabled', false).text(originalText);
sessionData.verified = false;
showFeedback(`${error.message}`, 'error');
});
});
$('#mc-upload-file').on('change', function() {
let files = Array.from(this.files);
// FIX: NUR BILDER ZULASSEN (Client Side Filter)
files = files.filter(function(f) {
return f.type.startsWith('image/');
});
if (files.length > 0) {
// Wenn Dateien gefiltert wurden (User hat PDF ausgewählt), aktualisiere Input
if (files.length !== this.files.length) {
const dataTransfer = new DataTransfer();
files.forEach(file => dataTransfer.items.add(file));
this.files = dataTransfer.files;
showFeedback('❌ Nur Bilder sind erlaubt! PDFs/Zip wurden entfernt.', 'error');
}
selectedFiles = files;
renderFilePreview();
}
});
$(document).on('click', '.mc-preview-remove', function() {
const index = $(this).data('index');
selectedFiles.splice(index, 1);
renderFilePreview();
const dataTransfer = new DataTransfer();
selectedFiles.forEach(file => dataTransfer.items.add(file));
$('#mc-upload-file')[0].files = dataTransfer.files;
});
$('#mc-btn-new-album').on('click', function() {
$('#mc-new-album-form').slideToggle();
});
$('#mc-btn-create-album').on('click', function() {
const albumName = $('#mc-new-album-name').val().trim();
if (!albumName) {
showFeedback('Bitte gib einen Album-Namen ein', 'error');
return;
}
const $btn = $(this);
$btn.prop('disabled', true).html('<span class="mc-loading"></span> Erstelle...');
const formData = new FormData();
formData.append('action', 'mc_gallery_create_album');
formData.append('mc_upload_nonce', mcGalleryPro.nonce);
formData.append('mc_token', sessionData.token || '');
formData.append('mc_username', sessionData.username);
formData.append('mc_server_id', sessionData.serverId || '');
formData.append('album_name', albumName);
fetch(ajaxUrl, {
method: 'POST',
body: formData,
credentials: 'same-origin'
})
.then(response => response.json())
.then(data => {
if (data.success) {
const $select = $('#mc-upload-album');
$select.append($('<option>')
.val(data.data.album.id)
.text(data.data.album.title)
);
$select.val(data.data.album.id);
$('#mc-new-album-name').val('');
$('#mc-new-album-form').slideUp();
showFeedback('✓ Album erfolgreich erstellt!', 'success');
} else {
showFeedback('Fehler: ' + (data.data?.message || 'Unbekannt'), 'error');
}
$btn.prop('disabled', false).text('Album erstellen');
})
.catch(error => {
console.error('Create album error:', error);
$btn.prop('disabled', false).text('Album erstellen');
showFeedback('Netzwerkfehler', 'error');
});
});
$('#mc-btn-final-upload').on('click', function () {
if (selectedFiles.length === 0) {
showFeedback('Bitte wähle mindestens ein Bild aus', 'error');
return;
}
if (selectedFiles.length > maxUploads) {
showFeedback('Du kannst nur ' + maxUploads + ' Bilder gleichzeitig hochladen.', 'error');
return;
}
// Auch ohne Token erlauben, wenn Forum-Session aktiv
if (!sessionData.verified || !sessionData.username) {
showFeedback('Bitte verifiziere dich zuerst.', 'error');
return;
}
const formData = new FormData();
formData.append('action', 'mc_gallery_upload');
formData.append('mc_upload_nonce', mcGalleryPro.nonce);
formData.append('mc_token', sessionData.token || '');
formData.append('mc_username', sessionData.username);
formData.append('mc_server_id', sessionData.serverId);
formData.append('mc_album_id', $('#mc-upload-album').val() || '');
selectedFiles.forEach((file) => {
formData.append('mc_images[]', file);
});
const $btn = $(this);
$btn.prop('disabled', true).hide();
$('#mc-upload-progress').show();
$('#mc-progress-text').text(`Lade ${selectedFiles.length} Bild${selectedFiles.length > 1 ? 'er' : ''} hoch...`);
let progress = 0;
const progressInterval = setInterval(() => {
progress += 5;
if (progress > 90) progress = 90;
$('#mc-progress-fill').css('width', progress + '%');
}, 200);
fetch(ajaxUrl, {
method: 'POST',
body: formData,
credentials: 'same-origin'
})
.then(response => response.json())
.then(data => {
clearInterval(progressInterval);
$('#mc-progress-fill').css('width', '100%');
if (data.success) {
const uploaded = data.data.uploaded || [];
const errors = data.data.errors || [];
let msg = `${uploaded.length} Bild${uploaded.length > 1 ? 'er' : ''} erfolgreich hochgeladen!`;
if (errors.length > 0) {
msg += `<br>⚠ ${errors.length} Fehler: ${errors.join(', ')}`;
}
showFeedback(msg, 'success');
setTimeout(() => {
window.location.reload();
}, 1500);
} else {
throw new Error(data.data?.message || data.message || 'Upload fehlgeschlagen');
}
})
.catch(error => {
clearInterval(progressInterval);
console.error('Upload error:', error);
$('#mc-upload-progress').hide();
$('#mc-progress-fill').css('width', '0%');
$btn.show().prop('disabled', false);
showFeedback(`❌ Upload Fehler: ${error.message}`, 'error');
});
});
$('#mc-btn-upload-more').on('click', function() {
$(this).hide();
$('#mc-feedback-msg').hide();
$('#mc-upload-file').click();
});
// === VOTE BUTTONS (Daumen hoch / runter) ===
if (mcGalleryPro.votingEnabled) {
// Cookie-Zustand initialisieren
function initVoteBtns() {
$('.mc-vote-wrap').each(function() {
const aid = $(this).data('attach-id');
const up = document.cookie.split(';').some(c => c.trim() === 'mc_vote_' + aid + '=up');
const down = document.cookie.split(';').some(c => c.trim() === 'mc_vote_' + aid + '=down');
if (up) $(this).find('.mc-vote-up').addClass('mc-vote-btn--active');
if (down) $(this).find('.mc-vote-down').addClass('mc-vote-btn--active');
});
}
initVoteBtns();
$(document).on('click', '.mc-vote-btn', function(e) {
e.preventDefault();
e.stopPropagation();
const $btn = $(this);
const $wrap = $btn.closest('.mc-vote-wrap');
const aid = $wrap.data('attach-id');
const nonce = $wrap.data('nonce');
const type = $btn.data('type'); // 'up' oder 'down'
const ck = 'mc_vote_' + aid;
const current = document.cookie.split(';').find(c => c.trim().startsWith(ck + '='));
const curVal = current ? current.trim().split('=')[1] : null;
if ($btn.prop('disabled')) return;
$wrap.find('.mc-vote-btn').prop('disabled', true);
// Toggle-Logik: nochmal klicken = entfernen
const isActive = $btn.hasClass('mc-vote-btn--active');
const action = isActive ? 'remove' : 'add';
$.post(ajaxUrl, {
action: 'mc_gallery_vote',
attach_id: aid,
vote_type: type,
vote_action: action,
nonce: nonce
})
.done(function(r) {
if (r.success) {
$wrap.find('.mc-vote-up-count').text(r.data.votes_up);
$wrap.find('.mc-vote-down-count').text(r.data.votes_down);
if (action === 'add') {
// Gegenpart deaktivieren falls aktiv
const other = type === 'up' ? 'down' : 'up';
$wrap.find('.mc-vote-' + other).removeClass('mc-vote-btn--active');
$btn.addClass('mc-vote-btn--active');
const exp = new Date(); exp.setDate(exp.getDate() + 30);
document.cookie = ck + '=' + type + '; expires=' + exp.toUTCString() + '; path=/; SameSite=Lax';
} else {
$btn.removeClass('mc-vote-btn--active');
document.cookie = ck + '=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/';
}
// Lightbox-Zähler synchronisieren
$('.mc-vote-wrap[data-attach-id="' + aid + '"] .mc-vote-up-count').text(r.data.votes_up);
$('.mc-vote-wrap[data-attach-id="' + aid + '"] .mc-vote-down-count').text(r.data.votes_down);
}
$wrap.find('.mc-vote-btn').prop('disabled', false);
})
.fail(function() {
$wrap.find('.mc-vote-btn').prop('disabled', false);
});
});
}
// === LIGHTBOX & VIEW COUNT ===
$(document).on('click', '.mc-gallery-item', function (e) {
e.preventDefault();
const $item = $(this);
const href = $item.attr('href');
if (!href) return;
// View Count Trigger
// Wir lesen die ID aus data-attach (müssen wir im Shortcode hinzufügen) oder versuchen sie aus der URL zu ermitteln
// Besser: Wir übergeben die Attach-ID im data-Attribut
const attachId = $item.data('attach-id');
const $badge = $item.find('.mc-views-badge');
if (attachId && $badge.length) {
incrementViewCount(attachId, $badge);
}
const player = $item.data('player') || $item.find('.mc-watermark').text().trim();
const date = $item.data('date') || '';
const album = $item.data('album') || '';
const $lightbox = $('<div class="mc-lightbox active"></div>');
const $content = $('<div class="mc-lightbox-content"></div>');
const $img = $('<img>').attr({ src: href, alt: player });
const $close = $('<button class="mc-lightbox-close" aria-label="Schließen">&times;</button>');
// Info-Zeile
let infoHtml = '';
if (player) infoHtml += `👤 ${player}`;
if (date && player) infoHtml += ' • ';
if (date) infoHtml += `📅 ${date}`;
if (album) infoHtml += ` • 📁 ${album}`;
if (infoHtml) {
const $info = $('<div class="mc-lightbox-info"></div>').html(infoHtml);
$content.append($info);
}
// Vote-Buttons in Lightbox
if (attachId) {
const $voteWrap = $item.find('.mc-vote-wrap').clone();
if ($voteWrap.length) {
$voteWrap.addClass('mc-vote-wrap--lightbox');
$content.append($voteWrap);
// Cookie-Zustand wiederherstellen
const ck = 'mc_vote_' + attachId;
const cur = document.cookie.split(';').find(c => c.trim().startsWith(ck + '='));
const curV = cur ? cur.trim().split('=')[1] : null;
if (curV === 'up') $voteWrap.find('.mc-vote-up').addClass('mc-vote-btn--active');
if (curV === 'down') $voteWrap.find('.mc-vote-down').addClass('mc-vote-btn--active');
}
}
$content.append($close).append($img);
$lightbox.append($content).appendTo('body');
$lightbox.on('click', function(e) {
if (e.target === this) {
$(this).removeClass('active');
setTimeout(() => $(this).remove(), 300);
}
});
$close.on('click', function() {
$lightbox.removeClass('active');
setTimeout(() => $lightbox.remove(), 300);
});
$(document).on('keydown.lightbox', function(e) {
if (e.key === 'Escape') {
$lightbox.removeClass('active');
setTimeout(() => $lightbox.remove(), 300);
$(document).off('keydown.lightbox');
}
});
});
});
})(jQuery);