Files
Wordpress-MC-Gallery/assets/js/gallery-pro.js

620 lines
24 KiB
JavaScript
Raw Permalink 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);
if (!sessionData.token || !sessionData.verified) 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();
}
function closeModal() {
$('#mc-upload-modal').removeClass('open').attr('aria-hidden', 'true');
$('html').css('overflow', '');
$('body').css('padding-right', originalBodyPadding);
setTimeout(resetModal, 300);
}
$(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();
}
});
$('#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;
}
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();
});
// === 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 views = $item.data('views') || 0;
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>');
let infoHtml = '';
if (player) infoHtml += `👤 ${player}`;
if (date && player) infoHtml += ' • ';
if (date) infoHtml += `📅 ${date}`;
if (album) infoHtml += ` • 📁 ${album}`;
// Views auch in Lightbox zeigen
if (views) infoHtml += ' • 👁️ ' + views;
if (infoHtml) {
const $info = $('<div class="mc-lightbox-info"></div>').html(infoHtml);
$content.append($info);
}
$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);