comfykiosk/frontend/templates/index.html

138 lines
5.5 KiB
HTML

{% extends "base.html" %}
{% block content %}
<h1>{{ title }}</h1>
<div id="error" class="error" style="display: none;"></div>
<form id="generateForm" onsubmit="generateImage(event)">
<div class="form-group" style="text-align: center;">
{% if not fixed_workflow %}
<select name="workflow" required>
<option value="">Select a workflow...</option>
</select>
{% endif %}
{% if not hide_seed %}
<input type="number" name="seed" min="0" placeholder="Leave empty for random seed">
{% endif %}
<button type="submit">Generate Image</button>
</div>
</form>
<div id="loading" style="display: none;"></div>
<div id="result">
<div class="image-container">
<img id="generatedImage" style="max-width: 512px; max-height: 512px; display: none; cursor: pointer;">
<div class="loading-overlay">
<div class="spinner"></div>
</div>
</div>
</div>
<script>
function submitGenerate() {
const form = document.getElementById('generateForm');
const event = new Event('submit', {
bubbles: true,
cancelable: true,
});
form.dispatchEvent(event);
}
const API_URL = '{{ api_url }}';
{% if fixed_workflow %}const FIXED_WORKFLOW = '{{ fixed_workflow }}';{% endif %}
function generateImage(event) {
event.preventDefault();
const form = event.target;
const loading = document.getElementById('loading');
const image = document.getElementById('generatedImage');
const workflowId = {% if fixed_workflow %}FIXED_WORKFLOW{% else %}form.workflow.value{% endif %};
const seedInput = form.querySelector('input[name="seed"]');
const seed = seedInput ? seedInput.value : null;
loading.style.display = 'block';
const imageContainer = document.querySelector('.image-container');
const loadingOverlay = document.querySelector('.loading-overlay');
if (imageContainer) {
imageContainer.classList.add('generating');
}
if (loadingOverlay) {
loadingOverlay.style.display = 'flex';
}
// Construct the appropriate URL based on whether we have a seed
// Ensure we're using the full URL
const baseUrl = API_URL.replace(/\/$/, ''); // Remove trailing slash if present
const url = seed
? `${baseUrl}/workflows/${workflowId}/image/${seed}`
: `${baseUrl}/workflows/${workflowId}/image`;
fetch(url)
.then(response => {
if (!response.ok) throw new Error('Generation failed');
return response.blob();
})
.then(blob => {
const url = URL.createObjectURL(blob);
image.src = url;
image.style.display = 'block';
image.onclick = submitGenerate;
const imageContainer = document.querySelector('.image-container');
const loadingOverlay = document.querySelector('.loading-overlay');
if (imageContainer) {
imageContainer.classList.remove('generating');
}
if (loadingOverlay) {
loadingOverlay.style.display = 'none';
}
})
.catch(error => {
alert('Error: ' + error.message);
const imageContainer = document.querySelector('.image-container');
const loadingOverlay = document.querySelector('.loading-overlay');
if (imageContainer) {
imageContainer.classList.remove('generating');
}
if (loadingOverlay) {
loadingOverlay.style.display = 'none';
}
});
}
// Load workflows when page loads
window.addEventListener('load', async () => {
{% if fixed_workflow %}
// Skip workflow loading if we're using a fixed workflow
return;
{% else %}
try {
const baseUrl = API_URL.replace(/\/$/, ''); // Remove trailing slash if present
const response = await fetch(`${baseUrl}/workflows`);
if (!response.ok) throw new Error('Failed to fetch workflows');
const workflows = await response.json();
const select = document.querySelector('select[name="workflow"]');
workflows.forEach(workflow => {
const option = document.createElement('option');
option.value = workflow.id;
option.textContent = `${workflow.id} - ${workflow.handle}`;
select.appendChild(option);
});
// If there's only one workflow, select it automatically
if (workflows.length === 1) {
select.value = workflows[0].id;
}
} catch (error) {
const errorDiv = document.getElementById('error');
errorDiv.textContent = `Error: ${error.message}`;
errorDiv.style.display = 'block';
}
{% endif %}
});
</script>
{% endblock %}