317 lines
13 KiB
JavaScript
317 lines
13 KiB
JavaScript
document.addEventListener("DOMContentLoaded", function () {
|
|
const form = document.getElementById("imageForm");
|
|
const generatedImage = document.getElementById("generatedImage");
|
|
const generateBtn = document.getElementById("generateBtn");
|
|
const spinner = document.getElementById("spinner");
|
|
const buttonText = document.getElementById("buttonText");
|
|
const elapsedTime = document.getElementById("elapsedTime");
|
|
const positivePromptDisplay = document.getElementById("positivePromptDisplay");
|
|
const negativePromptDisplay = document.getElementById("negativePromptDisplay");
|
|
const promptDisplay = document.getElementById("promptDisplay");
|
|
const quickPromptsContainer = document.getElementById("quickPromptsContainer");
|
|
const positiveKeywordsContainer = document.getElementById("positiveKeywords");
|
|
const negativeKeywordsContainer = document.getElementById("negativeKeywords");
|
|
const askLLMButton = document.getElementById("askLLMButton");
|
|
const askLLMSpinner = document.getElementById("askLLMSpinner");
|
|
const askLLMText = document.getElementById("askLLMText");
|
|
const llmResponseTextarea = document.getElementById("llmResponse");
|
|
const useLLMResponseButton = document.getElementById("useLLMResponseButton");
|
|
const notification = document.getElementById("notification");
|
|
const resetBtn = document.getElementById("resetBtn");
|
|
const imageNavigation = document.getElementById("imageNavigation");
|
|
const prevImageBtn = document.getElementById("prevImage");
|
|
const nextImageBtn = document.getElementById("nextImage");
|
|
|
|
let timerInterval;
|
|
let startTime;
|
|
let imageHistory = []; // Cache to store generated images
|
|
let currentImageIndex = -1; // Current index in image history
|
|
|
|
// Function to start the timer
|
|
function startTimer() {
|
|
startTime = new Date().getTime(); // Reset the start time
|
|
elapsedTime.innerText = "(00:00)"; // Reset display time
|
|
elapsedTime.classList.remove("d-none");
|
|
timerInterval = setInterval(function () {
|
|
const now = new Date().getTime();
|
|
const distance = now - startTime;
|
|
const minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
|
|
const seconds = Math.floor((distance % (1000 * 60)) / 1000);
|
|
elapsedTime.innerText = `(${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')})`;
|
|
}, 1000);
|
|
}
|
|
|
|
// Function to stop the timer
|
|
function stopTimer() {
|
|
clearInterval(timerInterval);
|
|
elapsedTime.classList.add("d-none");
|
|
}
|
|
|
|
// Function to display the notification for LLM usage
|
|
function showNotification(message, type = 'success') {
|
|
notification.innerText = message;
|
|
notification.classList.remove("d-none", "alert-success", "alert-danger");
|
|
notification.classList.add(`alert-${type}`);
|
|
|
|
// Hide the notification after 3 seconds
|
|
setTimeout(() => {
|
|
notification.classList.add("d-none");
|
|
}, 3000);
|
|
}
|
|
|
|
// Automatically scroll to the image result when it is generated
|
|
function scrollToImage() {
|
|
generatedImage.scrollIntoView({ behavior: "smooth", block: "center" });
|
|
}
|
|
|
|
// Function to reset the form
|
|
resetBtn.addEventListener("click", function () {
|
|
document.getElementById("positivePrompt").value = "";
|
|
document.getElementById("negativePrompt").value = "";
|
|
llmResponseTextarea.value = "";
|
|
generatedImage.classList.add("d-none");
|
|
promptDisplay.classList.add("d-none");
|
|
useLLMResponseButton.classList.add("d-none");
|
|
spinner.classList.add("d-none");
|
|
buttonText.innerText = "Generate Image";
|
|
imageHistory = [];
|
|
currentImageIndex = -1;
|
|
imageNavigation.classList.add("d-none");
|
|
showNotification("The UI has been reset.");
|
|
});
|
|
|
|
// Function to dynamically load quick prompts from the server
|
|
function loadQuickPrompts() {
|
|
fetch("/quick_prompts/")
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
quickPromptsContainer.innerHTML = ''; // Clear any existing quick prompts
|
|
positiveKeywordsContainer.innerHTML = ''; // Clear positive prompt buttons
|
|
negativeKeywordsContainer.innerHTML = ''; // Clear negative prompt buttons
|
|
|
|
// Load Positive Quick Prompts
|
|
if (data["Positive Quick Prompts"]) {
|
|
data["Positive Quick Prompts"].forEach(prompt => {
|
|
const button = document.createElement('button');
|
|
button.type = 'button';
|
|
button.classList.add('btn', 'btn-secondary', 'btn-sm', 'me-2', 'mb-2');
|
|
button.innerText = prompt.label;
|
|
|
|
button.addEventListener('click', function () {
|
|
addPositiveKeyword(button, prompt.value);
|
|
});
|
|
|
|
positiveKeywordsContainer.appendChild(button);
|
|
});
|
|
}
|
|
|
|
// Load Negative Quick Prompts
|
|
if (data["Negative Quick Prompts"]) {
|
|
data["Negative Quick Prompts"].forEach(prompt => {
|
|
const button = document.createElement('button');
|
|
button.type = 'button';
|
|
button.classList.add('btn', 'btn-secondary', 'btn-sm', 'me-2', 'mb-2');
|
|
button.innerText = prompt.label;
|
|
|
|
button.addEventListener('click', function () {
|
|
addNegativeKeyword(button, prompt.value);
|
|
});
|
|
|
|
negativeKeywordsContainer.appendChild(button);
|
|
});
|
|
}
|
|
|
|
// Load Other Quick Prompt Categories (e.g., Halloween, Christmas)
|
|
for (const category in data) {
|
|
if (category !== "Positive Quick Prompts" && category !== "Negative Quick Prompts") {
|
|
const section = document.createElement('div');
|
|
section.classList.add('mb-3');
|
|
|
|
const heading = document.createElement('label');
|
|
heading.classList.add('form-label');
|
|
heading.innerText = category;
|
|
|
|
const buttonsContainer = document.createElement('div');
|
|
buttonsContainer.classList.add('keyword-suggestions');
|
|
|
|
// Generate buttons for each prompt
|
|
data[category].forEach(prompt => {
|
|
const button = document.createElement('button');
|
|
button.type = 'button';
|
|
button.classList.add('btn', 'btn-secondary', 'btn-sm', 'me-2', 'mb-2');
|
|
button.innerText = prompt.label;
|
|
|
|
button.addEventListener('click', function () {
|
|
addPositiveKeyword(button, prompt.value);
|
|
});
|
|
|
|
buttonsContainer.appendChild(button);
|
|
});
|
|
|
|
section.appendChild(heading);
|
|
section.appendChild(buttonsContainer);
|
|
quickPromptsContainer.appendChild(section);
|
|
}
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error("Error loading quick prompts:", error);
|
|
});
|
|
}
|
|
|
|
// Function to add keywords to input fields and disable buttons after selection
|
|
window.addPositiveKeyword = function (button, keyword) {
|
|
const positiveInput = document.getElementById("positivePrompt");
|
|
positiveInput.value = `${positiveInput.value} ${keyword}`.trim();
|
|
button.disabled = true; // Disable button after adding keyword
|
|
};
|
|
|
|
window.addNegativeKeyword = function (button, keyword) {
|
|
const negativeInput = document.getElementById("negativePrompt");
|
|
negativeInput.value = `${negativeInput.value} ${keyword}`.trim();
|
|
button.disabled = true; // Disable button after adding keyword
|
|
};
|
|
|
|
// Function to ask the LLM for a creative prompt
|
|
askLLMButton.addEventListener("click", function () {
|
|
const positivePrompt = document.getElementById("positivePrompt").value;
|
|
|
|
let promptToSend = positivePrompt.trim();
|
|
if (!promptToSend) {
|
|
promptToSend = "Generate a general creative idea.";
|
|
}
|
|
|
|
// Disable button and show spinner
|
|
askLLMButton.disabled = true;
|
|
askLLMSpinner.classList.remove("d-none");
|
|
askLLMText.innerText = "Processing...";
|
|
|
|
fetch("/ask_llm/", {
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "application/json"
|
|
},
|
|
body: JSON.stringify({ positive_prompt: promptToSend })
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
llmResponseTextarea.value = data.assistant_reply;
|
|
useLLMResponseButton.classList.remove("d-none"); // Show the button to use the LLM's response
|
|
|
|
// Re-enable button and hide spinner
|
|
askLLMButton.disabled = false;
|
|
askLLMSpinner.classList.add("d-none");
|
|
askLLMText.innerText = "Ask LLM for Creative Idea";
|
|
})
|
|
.catch(error => {
|
|
console.error("Error getting LLM response:", error);
|
|
askLLMButton.disabled = false;
|
|
askLLMSpinner.classList.add("d-none");
|
|
askLLMText.innerText = "Ask LLM for Creative Idea";
|
|
});
|
|
});
|
|
|
|
// Function to use the LLM's creative response as the positive prompt
|
|
useLLMResponseButton.addEventListener("click", function () {
|
|
const llmResponse = llmResponseTextarea.value;
|
|
document.getElementById("positivePrompt").value = llmResponse;
|
|
showNotification("LLM's creative prompt has been applied!");
|
|
});
|
|
|
|
// Form submission for generating image
|
|
form.addEventListener("submit", function (event) {
|
|
event.preventDefault();
|
|
|
|
// Reset the timer and disable the Generate button
|
|
generateBtn.disabled = true;
|
|
spinner.classList.remove("d-none");
|
|
buttonText.innerText = "Generating...";
|
|
startTimer(); // Start timer with a reset
|
|
|
|
// Get input values
|
|
const positivePrompt = document.getElementById("positivePrompt").value;
|
|
const negativePrompt = document.getElementById("negativePrompt").value;
|
|
const steps = document.getElementById("steps").value;
|
|
const width = document.getElementById("width").value;
|
|
const height = document.getElementById("height").value;
|
|
|
|
// Post image generation request
|
|
fetch("/generate_images/", {
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "application/json"
|
|
},
|
|
body: JSON.stringify({
|
|
positive_prompt: positivePrompt,
|
|
negative_prompt: negativePrompt,
|
|
steps: parseInt(steps),
|
|
width: parseInt(width),
|
|
height: parseInt(height)
|
|
})
|
|
})
|
|
.then(response => response.blob())
|
|
.then(imageBlob => {
|
|
const imageUrl = URL.createObjectURL(imageBlob);
|
|
generatedImage.src = imageUrl;
|
|
generatedImage.classList.remove("d-none");
|
|
|
|
// Cache the image in imageHistory and update the index
|
|
imageHistory.push(imageUrl);
|
|
currentImageIndex = imageHistory.length - 1;
|
|
updateImageNavigation();
|
|
scrollToImage(); // Automatically scroll to the image
|
|
|
|
// Display the selected prompts
|
|
positivePromptDisplay.innerText = positivePrompt;
|
|
negativePromptDisplay.innerText = negativePrompt;
|
|
promptDisplay.classList.remove("d-none");
|
|
|
|
// Reset the button and timer
|
|
generateBtn.disabled = false;
|
|
spinner.classList.add("d-none");
|
|
buttonText.innerText = "Generate Image";
|
|
stopTimer();
|
|
})
|
|
.catch(error => {
|
|
console.error("Error generating image:", error);
|
|
generateBtn.disabled = false;
|
|
spinner.classList.add("d-none");
|
|
buttonText.innerText = "Generate Image";
|
|
stopTimer();
|
|
showNotification("Failed to generate image. Please try again.", "danger");
|
|
});
|
|
});
|
|
|
|
// Function to update image navigation visibility and state
|
|
function updateImageNavigation() {
|
|
if (imageHistory.length > 1) {
|
|
imageNavigation.classList.remove("d-none");
|
|
} else {
|
|
imageNavigation.classList.add("d-none");
|
|
}
|
|
|
|
prevImageBtn.disabled = currentImageIndex <= 0;
|
|
nextImageBtn.disabled = currentImageIndex >= imageHistory.length - 1;
|
|
}
|
|
|
|
// Previous and Next Image Navigation
|
|
prevImageBtn.addEventListener("click", function () {
|
|
if (currentImageIndex > 0) {
|
|
currentImageIndex--;
|
|
generatedImage.src = imageHistory[currentImageIndex];
|
|
}
|
|
updateImageNavigation();
|
|
});
|
|
|
|
nextImageBtn.addEventListener("click", function () {
|
|
if (currentImageIndex < imageHistory.length - 1) {
|
|
currentImageIndex++;
|
|
generatedImage.src = imageHistory[currentImageIndex];
|
|
}
|
|
updateImageNavigation();
|
|
});
|
|
|
|
// Load quick prompts when the page is loaded
|
|
loadQuickPrompts();
|
|
});
|