Gertie01's picture
Upload folder using huggingface_hub
8bd9942 verified
document.addEventListener('DOMContentLoaded', () => {
const uploadInput = document.getElementById('image-upload');
const uploadButton = document.getElementById('upload-button');
const uploadDropzone = document.getElementById('upload-dropzone');
const uploadedPreviews = document.getElementById('uploaded-previews');
const imageSpots = Array.from(document.querySelectorAll('.image-spot'));
const textPrompt = document.getElementById('text-prompt');
const remixButton = document.getElementById('remix-button');
const statusMessage = document.getElementById('status-message');
const remixResult = document.getElementById('remix-result');
const resultImage = document.getElementById('result-image');
const resultPlaceholder = document.getElementById('result-placeholder');
// Store base64 data for images in spots
const imageSpotData = Array(3).fill(null);
// Store original draggable elements created from uploaded images
const draggableImages = new Map(); // Map<id, {element, src}>
let uploadedImageCounter = 0;
// --- Utility Functions ---
const showStatus = (message, type = 'loading') => {
statusMessage.textContent = message;
statusMessage.className = `status-message ${type}`;
statusMessage.style.display = 'block';
};
const hideStatus = () => {
statusMessage.style.display = 'none';
statusMessage.textContent = '';
};
const clearResult = () => {
resultImage.style.display = 'none';
resultImage.src = '';
resultPlaceholder.style.display = 'block';
};
// --- File Upload Logic ---
uploadButton.addEventListener('click', () => uploadInput.click());
uploadInput.addEventListener('change', (event) => {
handleFiles(event.target.files);
});
uploadDropzone.addEventListener('dragover', (event) => {
event.preventDefault();
uploadDropzone.classList.add('drag-over');
});
uploadDropzone.addEventListener('dragleave', () => {
uploadDropzone.classList.remove('drag-over');
});
uploadDropzone.addEventListener('drop', (event) => {
event.preventDefault();
uploadDropzone.classList.remove('drag-over');
handleFiles(event.dataTransfer.files);
});
function handleFiles(files) {
if (files.length === 0) return;
Array.from(files).forEach(file => {
if (!file.type.startsWith('image/')) return;
const reader = new FileReader();
reader.onload = (e) => {
const imgId = `uploaded-img-${uploadedImageCounter++}`;
createDraggableImage(e.target.result, imgId);
};
reader.readAsDataURL(file);
});
}
function createDraggableImage(src, id) {
const wrapper = document.createElement('div');
wrapper.className = 'uploaded-image-wrapper';
wrapper.draggable = true;
wrapper.id = id;
const img = document.createElement('img');
img.src = src;
img.alt = `Uploaded image ${id}`;
const removeBtn = document.createElement('button');
removeBtn.className = 'remove-image';
removeBtn.textContent = 'x';
removeBtn.title = 'Remove image';
removeBtn.addEventListener('click', (e) => {
e.stopPropagation(); // Prevent drag event from firing
wrapper.remove();
draggableImages.delete(id);
// Also check if this image was in any spot and remove it
for (let i = 0; i < imageSpotData.length; i++) {
if (imageSpotData[i] && imageSpotData[i].id === id) {
clearImageSpot(imageSpots[i], i);
}
}
});
wrapper.appendChild(img);
wrapper.appendChild(removeBtn);
uploadedPreviews.appendChild(wrapper);
draggableImages.set(id, { element: wrapper, src: src });
wrapper.addEventListener('dragstart', (e) => {
e.dataTransfer.setData('text/plain', id);
e.dataTransfer.effectAllowed = 'copyMove';
// Optional: add a class to the original to make it transparent or similar
// e.target.classList.add('dragging');
});
// wrapper.addEventListener('dragend', (e) => {
// e.target.classList.remove('dragging');
// });
}
// --- Image Spot Drag & Drop Logic ---
imageSpots.forEach((spot) => {
spot.addEventListener('dragover', (event) => {
event.preventDefault();
spot.classList.add('drag-over');
event.dataTransfer.dropEffect = 'copy';
});
spot.addEventListener('dragleave', () => {
spot.classList.remove('drag-over');
});
spot.addEventListener('drop', (event) => {
event.preventDefault();
spot.classList.remove('drag-over');
const draggedId = event.dataTransfer.getData('text/plain');
const draggedImageData = draggableImages.get(draggedId);
if (draggedImageData) {
const spotIndex = parseInt(spot.dataset.index);
renderImageInSpot(spot, draggedImageData.src);
imageSpotData[spotIndex] = { src: draggedImageData.src, id: draggedId };
}
});
});
function renderImageInSpot(spotElement, imgSrc) {
const imgElement = spotElement.querySelector('.spot-image');
imgElement.src = imgSrc;
spotElement.classList.add('has-image');
imgElement.alt = `Image in spot ${spotElement.dataset.index + 1}`;
// Remove old image's alt if it exists and wasn't placeholder.
}
function clearImageSpot(spotElement, spotIndex) {
const imgElement = spotElement.querySelector('.spot-image');
imgElement.src = 'assets/img/placeholder.png'; // Reset to placeholder
spotElement.classList.remove('has-image');
imgElement.alt = `Image spot ${spotIndex + 1}`;
imageSpotData[spotIndex] = null;
}
// --- Remix Logic ---
remixButton.addEventListener('click', remixImages);
async function remixImages() {
hideStatus();
clearResult();
const images = imageSpotData.filter(data => data !== null);
const prompt = textPrompt.value.trim();
const selectedModel = document.querySelector('input[name="ai-model"]:checked').value;
if (images.length === 0) {
showStatus('Please drag at least one image into a spot.', 'error');
return;
}
if (!prompt) {
showStatus('Please enter a text prompt.', 'error');
return;
}
showStatus(`Remixing with ${selectedModel}... This is a simulation.`, 'loading');
try {
// Simulate API call
await new Promise(resolve => setTimeout(resolve, 3000)); // Simulate network delay
// In a real application, you would send `images` (base64 or URLs), `prompt`, and `selectedModel`
// to a backend API that integrates with Gemini-2 or GPT Image-1.
// The backend would then return the generated image's URL or base64.
// For simulation, we'll use a placeholder image based on the model
const placeholderResult = selectedModel === 'gemini-2'
? 'https://picsum.photos/seed/gemini/800/600?grayscale' // A bit more abstract
: 'https://picsum.photos/seed/gpt/800/600'; // Standard realistic
resultImage.src = placeholderResult;
resultImage.style.display = 'block';
resultPlaceholder.style.display = 'none';
showStatus('Remix successful! (Simulated)', 'success');
statusMessage.style.backgroundColor = '#d4edda'; // Light green for success
statusMessage.style.color = '#155724';
statusMessage.style.borderColor = '#28a745';
} catch (error) {
console.error('Remix error (simulated):', error);
showStatus('Failed to remix images. Please try again. (Simulated Error)', 'error');
}
}
});
// Initial state for result section
document.addEventListener('DOMContentLoaded', () => {
const resultImage = document.getElementById('result-image');
const resultPlaceholder = document.getElementById('result-placeholder');
resultImage.style.display = 'none';
resultPlaceholder.style.display = 'block';
});