Skip to content

Commit 76cfe1f

Browse files
authored
feat(image-gen/UI): move controls to the left, make the page more compact (#7823)
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
1 parent 5ee6c18 commit 76cfe1f

2 files changed

Lines changed: 257 additions & 237 deletions

File tree

core/http/static/image.js

Lines changed: 44 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -32,17 +32,24 @@ async function promptDallE() {
3232
const input = document.getElementById("input");
3333
const generateBtn = document.getElementById("generate-btn");
3434
const resultDiv = document.getElementById("result");
35+
const resultPlaceholder = document.getElementById("result-placeholder");
3536

3637
// Show loader and disable form
37-
loader.style.display = "block";
38+
loader.classList.remove("hidden");
39+
if (resultPlaceholder) {
40+
resultPlaceholder.style.display = "none";
41+
}
3842
input.disabled = true;
3943
generateBtn.disabled = true;
4044

4145
// Store the prompt for later restoration
4246
const prompt = input.value.trim();
4347
if (!prompt) {
4448
alert("Please enter a prompt");
45-
loader.style.display = "none";
49+
loader.classList.add("hidden");
50+
if (resultPlaceholder) {
51+
resultPlaceholder.style.display = "flex";
52+
}
4653
input.disabled = false;
4754
generateBtn.disabled = false;
4855
return;
@@ -103,8 +110,11 @@ async function promptDallE() {
103110
}
104111
} catch (error) {
105112
console.error("Error processing image files:", error);
106-
resultDiv.innerHTML = '<p class="text-red-500">Error processing image files: ' + error.message + '</p>';
107-
loader.style.display = "none";
113+
resultDiv.innerHTML = '<p class="text-xs text-red-500 p-2">Error processing image files: ' + error.message + '</p>';
114+
loader.classList.add("hidden");
115+
if (resultPlaceholder) {
116+
resultPlaceholder.style.display = "none";
117+
}
108118
input.disabled = false;
109119
generateBtn.disabled = false;
110120
return;
@@ -124,21 +134,27 @@ async function promptDallE() {
124134

125135
if (json.error) {
126136
// Display error
127-
resultDiv.innerHTML = '<p class="text-red-500 p-4">Error: ' + json.error.message + '</p>';
128-
loader.style.display = "none";
137+
resultDiv.innerHTML = '<p class="text-xs text-red-500 p-2">Error: ' + json.error.message + '</p>';
138+
loader.classList.add("hidden");
139+
if (resultPlaceholder) {
140+
resultPlaceholder.style.display = "none";
141+
}
129142
input.disabled = false;
130143
generateBtn.disabled = false;
131144
return;
132145
}
133146

134-
// Clear result div
147+
// Clear result div and hide placeholder
135148
resultDiv.innerHTML = '';
149+
if (resultPlaceholder) {
150+
resultPlaceholder.style.display = "none";
151+
}
136152

137153
// Display all generated images
138154
if (json.data && json.data.length > 0) {
139155
json.data.forEach((item, index) => {
140156
const imageContainer = document.createElement("div");
141-
imageContainer.className = "mb-6 bg-[var(--color-bg-primary)]/50 border border-[#1E293B] rounded-xl p-4";
157+
imageContainer.className = "mb-4 bg-[var(--color-bg-primary)]/50 border border-[#1E293B] rounded-lg p-2";
142158

143159
// Create image element
144160
const img = document.createElement("img");
@@ -150,30 +166,30 @@ async function promptDallE() {
150166
return; // Skip invalid items
151167
}
152168
img.alt = prompt;
153-
img.className = "w-full h-auto rounded-lg mb-3";
169+
img.className = "w-full h-auto rounded-lg mb-2";
154170
imageContainer.appendChild(img);
155171

156172
// Create caption container
157173
const captionDiv = document.createElement("div");
158-
captionDiv.className = "mt-3 p-3 bg-[var(--color-bg-secondary)] rounded-lg";
174+
captionDiv.className = "mt-2 p-2 bg-[var(--color-bg-secondary)] rounded-lg";
159175

160176
// Prompt caption
161177
const promptCaption = document.createElement("p");
162-
promptCaption.className = "text-sm text-[var(--color-text-primary)] mb-2";
178+
promptCaption.className = "text-xs text-[var(--color-text-primary)] mb-1.5";
163179
promptCaption.innerHTML = '<strong>Prompt:</strong> ' + escapeHtml(prompt);
164180
captionDiv.appendChild(promptCaption);
165181

166182
// Negative prompt if provided
167183
if (negativePrompt) {
168184
const negativeCaption = document.createElement("p");
169-
negativeCaption.className = "text-sm text-[var(--color-text-secondary)] mb-2";
185+
negativeCaption.className = "text-xs text-[var(--color-text-secondary)] mb-1.5";
170186
negativeCaption.innerHTML = '<strong>Negative Prompt:</strong> ' + escapeHtml(negativePrompt);
171187
captionDiv.appendChild(negativeCaption);
172188
}
173189

174190
// Generation details
175191
const detailsDiv = document.createElement("div");
176-
detailsDiv.className = "flex flex-wrap gap-4 text-xs text-[var(--color-text-secondary)] mt-2";
192+
detailsDiv.className = "flex flex-wrap gap-3 text-[10px] text-[var(--color-text-secondary)] mt-1.5";
177193
detailsDiv.innerHTML = `
178194
<span><strong>Size:</strong> ${size}</span>
179195
${step !== undefined ? `<span><strong>Steps:</strong> ${step}</span>` : ''}
@@ -183,7 +199,7 @@ async function promptDallE() {
183199

184200
// Copy prompt button
185201
const copyBtn = document.createElement("button");
186-
copyBtn.className = "mt-2 px-3 py-1 text-xs bg-[var(--color-primary)] text-white rounded hover:opacity-80";
202+
copyBtn.className = "mt-1.5 px-2 py-0.5 text-[10px] bg-[var(--color-primary)] text-white rounded hover:opacity-80";
187203
copyBtn.innerHTML = '<i class="fas fa-copy mr-1"></i>Copy Prompt';
188204
copyBtn.onclick = () => {
189205
navigator.clipboard.writeText(prompt).then(() => {
@@ -198,19 +214,29 @@ async function promptDallE() {
198214
imageContainer.appendChild(captionDiv);
199215
resultDiv.appendChild(imageContainer);
200216
});
217+
// Hide placeholder when images are displayed
218+
if (resultPlaceholder) {
219+
resultPlaceholder.style.display = "none";
220+
}
201221
} else {
202-
resultDiv.innerHTML = '<p class="text-[var(--color-text-secondary)] p-4">No images were generated.</p>';
222+
resultDiv.innerHTML = '<p class="text-xs text-[var(--color-text-secondary)] p-2">No images were generated.</p>';
223+
if (resultPlaceholder) {
224+
resultPlaceholder.style.display = "none";
225+
}
203226
}
204227

205228
// Preserve prompt in input field (don't clear it)
206229
// The prompt is already in the input field, so we don't need to restore it
207230

208231
} catch (error) {
209232
console.error("Error generating image:", error);
210-
resultDiv.innerHTML = '<p class="text-red-500 p-4">Error: ' + error.message + '</p>';
233+
resultDiv.innerHTML = '<p class="text-xs text-red-500 p-2">Error: ' + error.message + '</p>';
234+
if (resultPlaceholder) {
235+
resultPlaceholder.style.display = "none";
236+
}
211237
} finally {
212238
// Hide loader and re-enable form
213-
loader.style.display = "none";
239+
loader.classList.add("hidden");
214240
input.disabled = false;
215241
generateBtn.disabled = false;
216242
input.focus();
@@ -250,6 +276,6 @@ document.addEventListener("DOMContentLoaded", function() {
250276
// Hide loader initially
251277
const loader = document.getElementById("loader");
252278
if (loader) {
253-
loader.style.display = "none";
279+
loader.classList.add("hidden");
254280
}
255281
});

0 commit comments

Comments
 (0)