|
|
|
document.addEventListener('DOMContentLoaded', function () { |
|
|
|
class Logger { |
|
static debug(message, data = null) { |
|
console.log(`[Debug] ${message}`, data || ''); |
|
} |
|
|
|
static error(message, error = null) { |
|
console.error(`[Error] ${message}`, error || ''); |
|
} |
|
} |
|
|
|
|
|
function showLoading() { |
|
document.body.classList.add('loading'); |
|
} |
|
|
|
function hideLoading() { |
|
document.body.classList.remove('loading'); |
|
} |
|
|
|
|
|
function openImageModal(img) { |
|
Logger.debug('Opening image modal', img); |
|
const modal = new bootstrap.Modal(document.getElementById('imageModal')); |
|
const modalImg = document.getElementById('modalImage'); |
|
const filename = img.dataset.filename; |
|
|
|
|
|
modalImg.src = img.src; |
|
document.getElementById('modalFilename').textContent = filename; |
|
document.getElementById('modalFormat').textContent = img.dataset.format; |
|
document.getElementById('modalTimestamp').textContent = img.dataset.timestamp; |
|
document.getElementById('modalAlbum').textContent = img.dataset.album; |
|
document.getElementById('modalCategory').textContent = img.dataset.category; |
|
document.getElementById('modalPrompt').textContent = img.dataset.prompt; |
|
document.getElementById('modalOptimizedPrompt').textContent = img.dataset.optimized_prompt; |
|
|
|
|
|
document.querySelector('.image-container').onclick = function(e) { |
|
if (e.target === modalImg) { |
|
modal.hide(); |
|
} |
|
}; |
|
|
|
|
|
document.getElementById('modalDownloadBtn').onclick = async function() { |
|
await downloadSingleImage(filename); |
|
}; |
|
|
|
modal.show(); |
|
} |
|
|
|
|
|
|
|
async function downloadSingleImage(filename) { |
|
try { |
|
showLoading(); |
|
console.log('Attempting to download:', filename); |
|
|
|
const response = await fetch('/flux-pics/single', { |
|
method: 'POST', |
|
headers: { 'Content-Type': 'application/json' }, |
|
body: JSON.stringify({ filename }) |
|
}); |
|
|
|
if (!response.ok) { |
|
const errorText = await response.text(); |
|
console.error('Server Error:', errorText); |
|
throw new Error(`HTTP error! status: ${response.status}`); |
|
} |
|
|
|
const blob = await response.blob(); |
|
console.log('Download successful, creating blob URL'); |
|
const url = window.URL.createObjectURL(blob); |
|
const a = document.createElement('a'); |
|
a.style.display = 'none'; |
|
a.href = url; |
|
a.download = filename; |
|
document.body.appendChild(a); |
|
a.click(); |
|
window.URL.revokeObjectURL(url); |
|
hideLoading(); |
|
} catch (error) { |
|
console.error('Download error:', error); |
|
hideLoading(); |
|
alert('Ein Fehler ist aufgetreten: ' + error.message); |
|
} |
|
} |
|
|
|
|
|
document.addEventListener('DOMContentLoaded', function () { |
|
|
|
|
|
function getSelectedImages() { |
|
const selectedImages = []; |
|
const checkboxes = document.querySelectorAll('.select-item:checked'); |
|
Logger.debug(`Found ${checkboxes.length} selected images`); |
|
|
|
checkboxes.forEach(checkbox => { |
|
const img = checkbox.closest('.card').querySelector('img'); |
|
if (img && img.getAttribute('data-filename')) { |
|
selectedImages.push(img.getAttribute('data-filename')); |
|
} else { |
|
Logger.error('Missing image or filename for selected checkbox'); |
|
} |
|
}); |
|
return selectedImages; |
|
} |
|
|
|
|
|
const selectAllCheckbox = document.getElementById('selectAll'); |
|
if (selectAllCheckbox) { |
|
const itemCheckboxes = document.querySelectorAll('.select-item'); |
|
selectAllCheckbox.addEventListener('change', function () { |
|
itemCheckboxes.forEach(checkbox => { |
|
checkbox.checked = selectAllCheckbox.checked; |
|
}); |
|
}); |
|
} |
|
|
|
|
|
|
|
document.getElementById('thumbgalleryBtn').addEventListener('click', function () { |
|
const selectedImages = getSelectedImages(); |
|
if (selectedImages.length === 0) { |
|
alert('Keine Bilder ausgewählt.'); |
|
return; |
|
} |
|
|
|
const galleryModal = new bootstrap.Modal(document.getElementById('thumbGalleryModal')); |
|
const galleryContainer = document.getElementById('thumbGalleryContainer'); |
|
galleryContainer.innerHTML = ''; |
|
|
|
selectedImages.forEach(filename => { |
|
const container = document.createElement('div'); |
|
container.className = 'thumb-container m-2'; |
|
|
|
const img = document.createElement('img'); |
|
img.src = `/flux-pics/${filename}`; |
|
img.className = 'img-thumbnail thumbnail-img'; |
|
img.dataset.filename = filename; |
|
img.style.maxWidth = '150px'; |
|
img.style.cursor = 'pointer'; |
|
|
|
const downloadBtn = document.createElement('button'); |
|
downloadBtn.className = 'btn btn-sm btn-primary download-thumb'; |
|
downloadBtn.innerHTML = '<i class="fas fa-download"></i>'; |
|
|
|
container.appendChild(img); |
|
container.appendChild(downloadBtn); |
|
galleryContainer.appendChild(container); |
|
|
|
|
|
img.addEventListener('click', () => openImageModal(img)); |
|
|
|
|
|
downloadBtn.addEventListener('click', async () => { |
|
await downloadSingleImage(filename); |
|
}); |
|
}); |
|
|
|
galleryModal.show(); |
|
}); |
|
|
|
|
|
document.getElementById('slideshowBtn').addEventListener('click', function () { |
|
const selectedImages = getSelectedImages(); |
|
if (selectedImages.length === 0) { |
|
alert('Keine Bilder ausgewählt.'); |
|
return; |
|
} |
|
|
|
const slideshowModal = new bootstrap.Modal(document.getElementById('slideshowModal')); |
|
const slideshowContainer = document.getElementById('slideshowContainer'); |
|
slideshowContainer.innerHTML = ''; |
|
|
|
let currentSlideIndex = 0; |
|
let slideshowInterval; |
|
const slideInterval = 3000; |
|
|
|
selectedImages.forEach((filename, index) => { |
|
const div = document.createElement('div'); |
|
div.classList.add('carousel-item'); |
|
if (index === 0) div.classList.add('active'); |
|
|
|
const img = document.createElement('img'); |
|
img.src = `/flux-pics/${filename}`; |
|
img.classList.add('d-block', 'w-100'); |
|
img.dataset.filename = filename; |
|
|
|
div.appendChild(img); |
|
slideshowContainer.appendChild(div); |
|
}); |
|
|
|
const carousel = new bootstrap.Carousel(document.getElementById('carouselExampleControls'), { |
|
interval: false |
|
}); |
|
|
|
|
|
const playBtn = document.getElementById('playSlideshow'); |
|
const pauseBtn = document.getElementById('pauseSlideshow'); |
|
|
|
playBtn.addEventListener('click', function() { |
|
slideshowInterval = setInterval(() => { |
|
carousel.next(); |
|
}, slideInterval); |
|
playBtn.style.display = 'none'; |
|
pauseBtn.style.display = 'block'; |
|
}); |
|
|
|
pauseBtn.addEventListener('click', function() { |
|
clearInterval(slideshowInterval); |
|
pauseBtn.style.display = 'none'; |
|
playBtn.style.display = 'block'; |
|
}); |
|
|
|
|
|
document.getElementById('fullscreenBtn').addEventListener('click', function() { |
|
const modalElement = document.getElementById('slideshowModal'); |
|
if (modalElement.requestFullscreen) { |
|
modalElement.requestFullscreen(); |
|
} else if (modalElement.webkitRequestFullscreen) { |
|
modalElement.webkitRequestFullscreen(); |
|
} else if (modalElement.msRequestFullscreen) { |
|
modalElement.msRequestFullscreen(); |
|
} |
|
}); |
|
|
|
|
|
document.getElementById('downloadCurrentSlide').addEventListener('click', async function() { |
|
const activeSlide = slideshowContainer.querySelector('.carousel-item.active img'); |
|
if (activeSlide) { |
|
await downloadSingleImage(activeSlide.dataset.filename); |
|
} |
|
}); |
|
|
|
slideshowModal.show(); |
|
}); |
|
|
|
|
|
async function downloadSingleImage(filename) { |
|
try { |
|
const response = await fetch('/flux-pics/single', { |
|
method: 'POST', |
|
headers: { 'Content-Type': 'application/json' }, |
|
body: JSON.stringify({ filename }) |
|
}); |
|
|
|
if (!response.ok) { |
|
throw new Error(`HTTP error! status: ${response.status}`); |
|
} |
|
|
|
const blob = await response.blob(); |
|
const url = window.URL.createObjectURL(blob); |
|
const a = document.createElement('a'); |
|
a.style.display = 'none'; |
|
a.href = url; |
|
a.download = filename; |
|
document.body.appendChild(a); |
|
a.click(); |
|
window.URL.revokeObjectURL(url); |
|
} catch (error) { |
|
console.error('Fehler beim Download:', error); |
|
alert('Ein Fehler ist aufgetreten: ' + error.message); |
|
} |
|
} |
|
|
|
document.getElementById('gridLayout')?.addEventListener('change', function () { |
|
const columns = parseInt(this.value); |
|
const imageGrid = document.getElementById('imageGrid'); |
|
imageGrid.className = `row row-cols-1 row-cols-md-${columns}`; |
|
}); |
|
|
|
|
|
const scrollTopBtn = document.getElementById('scrollTopBtn'); |
|
if (scrollTopBtn) { |
|
window.addEventListener('scroll', function () { |
|
if (window.scrollY > 300) { |
|
scrollTopBtn.style.display = 'block'; |
|
} else { |
|
scrollTopBtn.style.display = 'none'; |
|
} |
|
}); |
|
|
|
scrollTopBtn.addEventListener('click', function () { |
|
window.scrollTo({ top: 0, behavior: 'smooth' }); |
|
}); |
|
} |
|
|
|
|
|
document.querySelectorAll('.image-thumbnail').forEach(function(img) { |
|
img.addEventListener('click', function() { |
|
openImageModal(this); |
|
}); |
|
}); |
|
|
|
|
|
document.getElementById('downloadSelected')?.addEventListener('click', async function () { |
|
const selectedImages = getSelectedImages(); |
|
Logger.debug('Selected images:', selectedImages); |
|
|
|
if (selectedImages.length === 0) { |
|
alert('Keine Bilder ausgewählt.'); |
|
return; |
|
} |
|
|
|
let downloadType = 'single'; |
|
if (selectedImages.length > 1) { |
|
const choice = confirm('Möchten Sie die Bilder als ZIP-Datei herunterladen?\nKlicken Sie "OK" für ZIP oder "Abbrechen" für Einzeldownloads.'); |
|
if (choice) { |
|
downloadType = 'zip'; |
|
} |
|
} |
|
|
|
try { |
|
if (downloadType === 'zip') { |
|
showLoading(); |
|
const response = await fetch('/flux-pics', { |
|
method: 'POST', |
|
headers: { 'Content-Type': 'application/json' }, |
|
body: JSON.stringify({ selectedImages }) |
|
}); |
|
|
|
if (!response.ok) { |
|
const errorText = await response.text(); |
|
Logger.error('Server Error:', errorText); |
|
throw new Error(`HTTP error! status: ${response.status}`); |
|
} |
|
|
|
const blob = await response.blob(); |
|
const url = window.URL.createObjectURL(blob); |
|
const a = document.createElement('a'); |
|
a.style.display = 'none'; |
|
a.href = url; |
|
a.download = 'images.zip'; |
|
document.body.appendChild(a); |
|
a.click(); |
|
window.URL.revokeObjectURL(url); |
|
hideLoading(); |
|
} else { |
|
for (const filename of selectedImages) { |
|
await downloadSingleImage(filename); |
|
await new Promise(resolve => setTimeout(resolve, 500)); |
|
} |
|
} |
|
alert('Download erfolgreich abgeschlossen.'); |
|
} catch (error) { |
|
Logger.error('Download error:', error); |
|
hideLoading(); |
|
alert('Ein Fehler ist aufgetreten: ' + error.message); |
|
} |
|
}); |
|
|
|
|
|
document.addEventListener('keydown', function(e) { |
|
if (e.key === 'Escape') { |
|
const modals = document.querySelectorAll('.modal.show'); |
|
modals.forEach(modal => { |
|
const bootstrapModal = bootstrap.Modal.getInstance(modal); |
|
if (bootstrapModal) bootstrapModal.hide(); |
|
}); |
|
} |
|
}); |
|
}); |
|
|
|
function getImagePath(filename) { |
|
return `/flux-pics/${filename}`; |
|
} |
|
|
|
|
|
img.src = getImagePath(filename); |
|
|