ComfyUI/web/scripts/gallery.js
google-labs-jules[bot] 9dc31cd71e feat: Add gallery feature for user images
This commit introduces a new gallery feature that allows you to mark images
in your user data folder and view them in a dedicated gallery page.

Key changes:

Backend (`app/user_manager.py`):
- Added a `GALLERY_SUFFIX` constant (`.gallery`).
- Implemented `toggle_gallery_status` to add/remove the gallery suffix from
  filenames (e.g., `image.png` <-> `image.gallery.png`).
- Added a POST route `/userdata/{file}/gallery` to toggle an image's gallery
  status.
- Implemented `list_gallery_files` to retrieve all images marked for the
  gallery.
- Added a GET route `/gallery` to list gallery items for you.

Frontend:
- Created `web/gallery.html` as the main page for the gallery view.
- Created `web/css/gallery.css` for basic styling of the gallery.
- Created `web/scripts/gallery.js` to fetch and display gallery items,
  allowing you to remove items from the gallery.
- Created `web/scripts/gallery_integration.js` to dynamically add a "Gallery"
  button/link to the main application UI, which navigates to `gallery.html`.
- Updated `web/index.html` to include the gallery integration script.

Tests (`tests-unit/app_test/user_manager_gallery_routes_test.py`):
- Added comprehensive unit tests for the new backend routes, covering:
  - Listing gallery items (empty, single, multiple, subdirectories).
  - Toggling gallery status (add, remove, file not found, invalid params).
  - Correct filename transformations and path handling.
2025-06-21 05:14:56 +00:00

78 lines
2.7 KiB
JavaScript
Vendored

document.addEventListener('DOMContentLoaded', () => {
initGallery();
});
async function initGallery() {
try {
const items = await fetchGalleryItems();
renderGalleryItems(items);
} catch (error) {
console.error("Error initializing gallery:", error);
const galleryContainer = document.getElementById('gallery-container');
if (galleryContainer) {
galleryContainer.innerHTML = '<p>Error loading gallery items. Please try again later.</p>';
}
}
}
async function fetchGalleryItems() {
const response = await fetch('/gallery');
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return await response.json();
}
function renderGalleryItems(items) {
const galleryContainer = document.getElementById('gallery-container');
if (!galleryContainer) {
console.error("Gallery container not found!");
return;
}
galleryContainer.innerHTML = ''; // Clear previous items
if (!items || items.length === 0) {
galleryContainer.innerHTML = '<p>No items in the gallery.</p>';
return;
}
items.forEach(item => {
const itemDiv = document.createElement('div');
itemDiv.className = 'gallery-item';
const img = document.createElement('img');
// Assuming 'item.path' is the correct relative path including any necessary subdirectories
// and the '.gallery' part of the filename.
img.src = `userdata/${item.path}`;
img.alt = item.filename;
img.className = 'gallery-thumbnail';
img.onerror = () => { // Basic error handling for broken images
img.alt = 'Image not found';
// Optionally, display a placeholder or hide the item
};
const removeButton = document.createElement('button');
removeButton.textContent = 'Remove from Gallery';
removeButton.onclick = async () => {
try {
// item.path should be the full relative path including any .gallery part
const response = await fetch(`/userdata/${item.path}/gallery`, { method: 'POST' });
if (!response.ok) {
const errorData = await response.json();
throw new Error(`Failed to remove item: ${errorData.error || response.status}`);
}
// Refresh the gallery to show changes
initGallery();
} catch (error) {
console.error('Error removing item from gallery:', error);
alert(`Error: ${error.message}`);
}
};
itemDiv.appendChild(img);
itemDiv.appendChild(removeButton);
galleryContainer.appendChild(itemDiv);
});
}