Scalino84 commited on
Commit
3c4f863
·
verified ·
1 Parent(s): 03b0d8c

Upload /bck/static/script.js with huggingface_hub

Browse files
Files changed (1) hide show
  1. bck/static/script.js +373 -0
bck/static/script.js ADDED
@@ -0,0 +1,373 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ document.addEventListener('DOMContentLoaded', function () {
3
+ // Hilfsklasse für Debug-Logging
4
+ class Logger {
5
+ static debug(message, data = null) {
6
+ console.log(`[Debug] ${message}`, data || '');
7
+ }
8
+
9
+ static error(message, error = null) {
10
+ console.error(`[Error] ${message}`, error || '');
11
+ }
12
+ }
13
+
14
+ // Utility-Funktionen
15
+ function showLoading() {
16
+ document.body.classList.add('loading');
17
+ }
18
+
19
+ function hideLoading() {
20
+ document.body.classList.remove('loading');
21
+ }
22
+
23
+ // Bild-Modal Funktionalität
24
+ function openImageModal(img) {
25
+ Logger.debug('Opening image modal', img);
26
+ const modal = new bootstrap.Modal(document.getElementById('imageModal'));
27
+ const modalImg = document.getElementById('modalImage');
28
+ const filename = img.dataset.filename;
29
+
30
+ // Bild und Metadaten setzen
31
+ modalImg.src = img.src;
32
+ document.getElementById('modalFilename').textContent = filename;
33
+ document.getElementById('modalFormat').textContent = img.dataset.format;
34
+ document.getElementById('modalTimestamp').textContent = img.dataset.timestamp;
35
+ document.getElementById('modalAlbum').textContent = img.dataset.album;
36
+ document.getElementById('modalCategory').textContent = img.dataset.category;
37
+ document.getElementById('modalPrompt').textContent = img.dataset.prompt;
38
+ document.getElementById('modalOptimizedPrompt').textContent = img.dataset.optimized_prompt;
39
+
40
+ // Click-to-Close Funktionalität
41
+ document.querySelector('.image-container').onclick = function(e) {
42
+ if (e.target === modalImg) {
43
+ modal.hide();
44
+ }
45
+ };
46
+
47
+ // Download-Button Funktionalität
48
+ document.getElementById('modalDownloadBtn').onclick = async function() {
49
+ await downloadSingleImage(filename);
50
+ };
51
+
52
+ modal.show();
53
+ }
54
+
55
+ // Download-Funktionalitäten
56
+ // Download functionality
57
+ async function downloadSingleImage(filename) {
58
+ try {
59
+ showLoading();
60
+ console.log('Attempting to download:', filename);
61
+
62
+ const response = await fetch('/flux-pics/single', {
63
+ method: 'POST',
64
+ headers: { 'Content-Type': 'application/json' },
65
+ body: JSON.stringify({ filename })
66
+ });
67
+
68
+ if (!response.ok) {
69
+ const errorText = await response.text();
70
+ console.error('Server Error:', errorText);
71
+ throw new Error(`HTTP error! status: ${response.status}`);
72
+ }
73
+
74
+ const blob = await response.blob();
75
+ console.log('Download successful, creating blob URL');
76
+ const url = window.URL.createObjectURL(blob);
77
+ const a = document.createElement('a');
78
+ a.style.display = 'none';
79
+ a.href = url;
80
+ a.download = filename;
81
+ document.body.appendChild(a);
82
+ a.click();
83
+ window.URL.revokeObjectURL(url);
84
+ hideLoading();
85
+ } catch (error) {
86
+ console.error('Download error:', error);
87
+ hideLoading();
88
+ alert('Ein Fehler ist aufgetreten: ' + error.message);
89
+ }
90
+ }
91
+
92
+ // Main initialization
93
+ document.addEventListener('DOMContentLoaded', function () {
94
+
95
+ // Auswahlfunktionen
96
+ function getSelectedImages() {
97
+ const selectedImages = [];
98
+ const checkboxes = document.querySelectorAll('.select-item:checked');
99
+ Logger.debug(`Found ${checkboxes.length} selected images`);
100
+
101
+ checkboxes.forEach(checkbox => {
102
+ const img = checkbox.closest('.card').querySelector('img');
103
+ if (img && img.getAttribute('data-filename')) {
104
+ selectedImages.push(img.getAttribute('data-filename'));
105
+ } else {
106
+ Logger.error('Missing image or filename for selected checkbox');
107
+ }
108
+ });
109
+ return selectedImages;
110
+ }
111
+
112
+ // Event Listener für "Alle auswählen" Checkbox
113
+ const selectAllCheckbox = document.getElementById('selectAll');
114
+ if (selectAllCheckbox) {
115
+ const itemCheckboxes = document.querySelectorAll('.select-item');
116
+ selectAllCheckbox.addEventListener('change', function () {
117
+ itemCheckboxes.forEach(checkbox => {
118
+ checkbox.checked = selectAllCheckbox.checked;
119
+ });
120
+ });
121
+ }
122
+
123
+ // Thumbnail-Galerie Funktionalität
124
+ // Thumbnail-Galerie Funktionalität
125
+ document.getElementById('thumbgalleryBtn').addEventListener('click', function () {
126
+ const selectedImages = getSelectedImages();
127
+ if (selectedImages.length === 0) {
128
+ alert('Keine Bilder ausgewählt.');
129
+ return;
130
+ }
131
+
132
+ const galleryModal = new bootstrap.Modal(document.getElementById('thumbGalleryModal'));
133
+ const galleryContainer = document.getElementById('thumbGalleryContainer');
134
+ galleryContainer.innerHTML = '';
135
+
136
+ selectedImages.forEach(filename => {
137
+ const container = document.createElement('div');
138
+ container.className = 'thumb-container m-2';
139
+
140
+ const img = document.createElement('img');
141
+ img.src = `/flux-pics/${filename}`;
142
+ img.className = 'img-thumbnail thumbnail-img';
143
+ img.dataset.filename = filename;
144
+ img.style.maxWidth = '150px';
145
+ img.style.cursor = 'pointer';
146
+
147
+ const downloadBtn = document.createElement('button');
148
+ downloadBtn.className = 'btn btn-sm btn-primary download-thumb';
149
+ downloadBtn.innerHTML = '<i class="fas fa-download"></i>';
150
+
151
+ container.appendChild(img);
152
+ container.appendChild(downloadBtn);
153
+ galleryContainer.appendChild(container);
154
+
155
+ // Klick auf Thumbnail öffnet Vollbild
156
+ img.addEventListener('click', () => openImageModal(img));
157
+
158
+ // Download Button
159
+ downloadBtn.addEventListener('click', async () => {
160
+ await downloadSingleImage(filename);
161
+ });
162
+ });
163
+
164
+ galleryModal.show();
165
+ });
166
+
167
+ // Slideshow Funktionalität
168
+ document.getElementById('slideshowBtn').addEventListener('click', function () {
169
+ const selectedImages = getSelectedImages();
170
+ if (selectedImages.length === 0) {
171
+ alert('Keine Bilder ausgewählt.');
172
+ return;
173
+ }
174
+
175
+ const slideshowModal = new bootstrap.Modal(document.getElementById('slideshowModal'));
176
+ const slideshowContainer = document.getElementById('slideshowContainer');
177
+ slideshowContainer.innerHTML = '';
178
+
179
+ let currentSlideIndex = 0;
180
+ let slideshowInterval;
181
+ const slideInterval = 3000; // 3 Sekunden pro Bild
182
+
183
+ selectedImages.forEach((filename, index) => {
184
+ const div = document.createElement('div');
185
+ div.classList.add('carousel-item');
186
+ if (index === 0) div.classList.add('active');
187
+
188
+ const img = document.createElement('img');
189
+ img.src = `/flux-pics/${filename}`;
190
+ img.classList.add('d-block', 'w-100');
191
+ img.dataset.filename = filename;
192
+
193
+ div.appendChild(img);
194
+ slideshowContainer.appendChild(div);
195
+ });
196
+
197
+ const carousel = new bootstrap.Carousel(document.getElementById('carouselExampleControls'), {
198
+ interval: false
199
+ });
200
+
201
+ // Play/Pause Funktionalität
202
+ const playBtn = document.getElementById('playSlideshow');
203
+ const pauseBtn = document.getElementById('pauseSlideshow');
204
+
205
+ playBtn.addEventListener('click', function() {
206
+ slideshowInterval = setInterval(() => {
207
+ carousel.next();
208
+ }, slideInterval);
209
+ playBtn.style.display = 'none';
210
+ pauseBtn.style.display = 'block';
211
+ });
212
+
213
+ pauseBtn.addEventListener('click', function() {
214
+ clearInterval(slideshowInterval);
215
+ pauseBtn.style.display = 'none';
216
+ playBtn.style.display = 'block';
217
+ });
218
+
219
+ // Vollbild Funktionalität
220
+ document.getElementById('fullscreenBtn').addEventListener('click', function() {
221
+ const modalElement = document.getElementById('slideshowModal');
222
+ if (modalElement.requestFullscreen) {
223
+ modalElement.requestFullscreen();
224
+ } else if (modalElement.webkitRequestFullscreen) {
225
+ modalElement.webkitRequestFullscreen();
226
+ } else if (modalElement.msRequestFullscreen) {
227
+ modalElement.msRequestFullscreen();
228
+ }
229
+ });
230
+
231
+ // Download aktuelles Bild
232
+ document.getElementById('downloadCurrentSlide').addEventListener('click', async function() {
233
+ const activeSlide = slideshowContainer.querySelector('.carousel-item.active img');
234
+ if (activeSlide) {
235
+ await downloadSingleImage(activeSlide.dataset.filename);
236
+ }
237
+ });
238
+
239
+ slideshowModal.show();
240
+ });
241
+
242
+ // Hilfsfunktion für Einzelbild-Download
243
+ async function downloadSingleImage(filename) {
244
+ try {
245
+ const response = await fetch('/flux-pics/single', {
246
+ method: 'POST',
247
+ headers: { 'Content-Type': 'application/json' },
248
+ body: JSON.stringify({ filename })
249
+ });
250
+
251
+ if (!response.ok) {
252
+ throw new Error(`HTTP error! status: ${response.status}`);
253
+ }
254
+
255
+ const blob = await response.blob();
256
+ const url = window.URL.createObjectURL(blob);
257
+ const a = document.createElement('a');
258
+ a.style.display = 'none';
259
+ a.href = url;
260
+ a.download = filename;
261
+ document.body.appendChild(a);
262
+ a.click();
263
+ window.URL.revokeObjectURL(url);
264
+ } catch (error) {
265
+ console.error('Fehler beim Download:', error);
266
+ alert('Ein Fehler ist aufgetreten: ' + error.message);
267
+ }
268
+ }
269
+ // Grid Layout Funktionalität
270
+ document.getElementById('gridLayout')?.addEventListener('change', function () {
271
+ const columns = parseInt(this.value);
272
+ const imageGrid = document.getElementById('imageGrid');
273
+ imageGrid.className = `row row-cols-1 row-cols-md-${columns}`;
274
+ });
275
+
276
+ // Scroll-to-Top Button
277
+ const scrollTopBtn = document.getElementById('scrollTopBtn');
278
+ if (scrollTopBtn) {
279
+ window.addEventListener('scroll', function () {
280
+ if (window.scrollY > 300) {
281
+ scrollTopBtn.style.display = 'block';
282
+ } else {
283
+ scrollTopBtn.style.display = 'none';
284
+ }
285
+ });
286
+
287
+ scrollTopBtn.addEventListener('click', function () {
288
+ window.scrollTo({ top: 0, behavior: 'smooth' });
289
+ });
290
+ }
291
+
292
+ // Event Listener für Bilddetails
293
+ document.querySelectorAll('.image-thumbnail').forEach(function(img) {
294
+ img.addEventListener('click', function() {
295
+ openImageModal(this);
296
+ });
297
+ });
298
+
299
+ // Download ausgewählter Bilder
300
+ document.getElementById('downloadSelected')?.addEventListener('click', async function () {
301
+ const selectedImages = getSelectedImages();
302
+ Logger.debug('Selected images:', selectedImages);
303
+
304
+ if (selectedImages.length === 0) {
305
+ alert('Keine Bilder ausgewählt.');
306
+ return;
307
+ }
308
+
309
+ let downloadType = 'single';
310
+ if (selectedImages.length > 1) {
311
+ const choice = confirm('Möchten Sie die Bilder als ZIP-Datei herunterladen?\nKlicken Sie "OK" für ZIP oder "Abbrechen" für Einzeldownloads.');
312
+ if (choice) {
313
+ downloadType = 'zip';
314
+ }
315
+ }
316
+
317
+ try {
318
+ if (downloadType === 'zip') {
319
+ showLoading();
320
+ const response = await fetch('/flux-pics', {
321
+ method: 'POST',
322
+ headers: { 'Content-Type': 'application/json' },
323
+ body: JSON.stringify({ selectedImages })
324
+ });
325
+
326
+ if (!response.ok) {
327
+ const errorText = await response.text();
328
+ Logger.error('Server Error:', errorText);
329
+ throw new Error(`HTTP error! status: ${response.status}`);
330
+ }
331
+
332
+ const blob = await response.blob();
333
+ const url = window.URL.createObjectURL(blob);
334
+ const a = document.createElement('a');
335
+ a.style.display = 'none';
336
+ a.href = url;
337
+ a.download = 'images.zip';
338
+ document.body.appendChild(a);
339
+ a.click();
340
+ window.URL.revokeObjectURL(url);
341
+ hideLoading();
342
+ } else {
343
+ for (const filename of selectedImages) {
344
+ await downloadSingleImage(filename);
345
+ await new Promise(resolve => setTimeout(resolve, 500));
346
+ }
347
+ }
348
+ alert('Download erfolgreich abgeschlossen.');
349
+ } catch (error) {
350
+ Logger.error('Download error:', error);
351
+ hideLoading();
352
+ alert('Ein Fehler ist aufgetreten: ' + error.message);
353
+ }
354
+ });
355
+
356
+ // Keyboard Navigation
357
+ document.addEventListener('keydown', function(e) {
358
+ if (e.key === 'Escape') {
359
+ const modals = document.querySelectorAll('.modal.show');
360
+ modals.forEach(modal => {
361
+ const bootstrapModal = bootstrap.Modal.getInstance(modal);
362
+ if (bootstrapModal) bootstrapModal.hide();
363
+ });
364
+ }
365
+ });
366
+ });
367
+
368
+ function getImagePath(filename) {
369
+ return `/flux-pics/${filename}`;
370
+ }
371
+
372
+ // Und dann verwenden Sie diese Funktion überall:
373
+ img.src = getImagePath(filename);