fluxi / bck /static /script.js
Scalino84's picture
Upload /bck/static/script.js with huggingface_hub
3c4f863 verified
document.addEventListener('DOMContentLoaded', function () {
// Hilfsklasse für Debug-Logging
class Logger {
static debug(message, data = null) {
console.log(`[Debug] ${message}`, data || '');
}
static error(message, error = null) {
console.error(`[Error] ${message}`, error || '');
}
}
// Utility-Funktionen
function showLoading() {
document.body.classList.add('loading');
}
function hideLoading() {
document.body.classList.remove('loading');
}
// Bild-Modal Funktionalität
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;
// Bild und Metadaten setzen
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;
// Click-to-Close Funktionalität
document.querySelector('.image-container').onclick = function(e) {
if (e.target === modalImg) {
modal.hide();
}
};
// Download-Button Funktionalität
document.getElementById('modalDownloadBtn').onclick = async function() {
await downloadSingleImage(filename);
};
modal.show();
}
// Download-Funktionalitäten
// Download functionality
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);
}
}
// Main initialization
document.addEventListener('DOMContentLoaded', function () {
// Auswahlfunktionen
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;
}
// Event Listener für "Alle auswählen" Checkbox
const selectAllCheckbox = document.getElementById('selectAll');
if (selectAllCheckbox) {
const itemCheckboxes = document.querySelectorAll('.select-item');
selectAllCheckbox.addEventListener('change', function () {
itemCheckboxes.forEach(checkbox => {
checkbox.checked = selectAllCheckbox.checked;
});
});
}
// Thumbnail-Galerie Funktionalität
// Thumbnail-Galerie Funktionalität
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);
// Klick auf Thumbnail öffnet Vollbild
img.addEventListener('click', () => openImageModal(img));
// Download Button
downloadBtn.addEventListener('click', async () => {
await downloadSingleImage(filename);
});
});
galleryModal.show();
});
// Slideshow Funktionalität
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; // 3 Sekunden pro Bild
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
});
// Play/Pause Funktionalität
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';
});
// Vollbild Funktionalität
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();
}
});
// Download aktuelles Bild
document.getElementById('downloadCurrentSlide').addEventListener('click', async function() {
const activeSlide = slideshowContainer.querySelector('.carousel-item.active img');
if (activeSlide) {
await downloadSingleImage(activeSlide.dataset.filename);
}
});
slideshowModal.show();
});
// Hilfsfunktion für Einzelbild-Download
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);
}
}
// Grid Layout Funktionalität
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}`;
});
// Scroll-to-Top Button
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' });
});
}
// Event Listener für Bilddetails
document.querySelectorAll('.image-thumbnail').forEach(function(img) {
img.addEventListener('click', function() {
openImageModal(this);
});
});
// Download ausgewählter Bilder
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);
}
});
// Keyboard Navigation
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}`;
}
// Und dann verwenden Sie diese Funktion überall:
img.src = getImagePath(filename);