Spaces:
Sleeping
Sleeping
Commit
·
d46cb20
1
Parent(s):
ac4f897
Match Z-Image UI exactly
Browse files- Updated CSS to match Z-Image Apple-style design
- Output section now has white background
- Removed Advanced Settings accordion
- Hidden footer links
- Always use random seed (like Z-Image)
- Fixed inference parameters (30 steps, 4.0 guidance)
- Improved JavaScript for layout control
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
app.py
CHANGED
|
@@ -196,20 +196,27 @@ def parse_aspect_ratio(aspect_ratio_str):
|
|
| 196 |
return int(match.group(1)), int(match.group(2))
|
| 197 |
return 1024, 1024 # Default
|
| 198 |
|
| 199 |
-
def infer(prompt, aspect_ratio="
|
|
|
|
|
|
|
|
|
|
| 200 |
|
| 201 |
-
|
| 202 |
-
|
| 203 |
|
| 204 |
# Parse aspect ratio to get width and height
|
| 205 |
width, height = parse_aspect_ratio(aspect_ratio)
|
| 206 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 207 |
# Text Encoding (Network bound - No GPU needed)
|
| 208 |
progress(0.1, desc="Encoding prompt...")
|
| 209 |
prompt_embeds = remote_text_encoder(prompt)
|
| 210 |
|
| 211 |
# Image Generation (GPU bound)
|
| 212 |
-
progress(0.3, desc="
|
| 213 |
image = generate_image(
|
| 214 |
prompt_embeds,
|
| 215 |
None, # No input images
|
|
@@ -221,7 +228,7 @@ def infer(prompt, aspect_ratio="1:1 (1024x1024)", seed=42, randomize_seed=False,
|
|
| 221 |
progress
|
| 222 |
)
|
| 223 |
|
| 224 |
-
return image
|
| 225 |
|
| 226 |
examples = [
|
| 227 |
["Create a vase on a table in living room, the color of the vase is a gradient of color, starting with #02eb3c color and finishing with #edfa3c. The flowers inside the vase have the color #ff0088"],
|
|
@@ -235,48 +242,24 @@ examples_images = [
|
|
| 235 |
["The person from image 1 is petting the cat from image 2, the bird from image 3 is next to them", ["woman1.webp", "cat_window.webp", "bird.webp"]]
|
| 236 |
]
|
| 237 |
|
| 238 |
-
# Apple-inspired CSS styling
|
| 239 |
css = """
|
| 240 |
-
/* Global
|
| 241 |
.gradio-container {
|
| 242 |
max-width: 85vw !important;
|
| 243 |
margin: 0 auto !important;
|
| 244 |
-
|
| 245 |
-
|
| 246 |
-
|
| 247 |
-
/* Main row - horizontal layout */
|
| 248 |
-
#main-row {
|
| 249 |
-
display: flex !important;
|
| 250 |
-
flex-direction: row !important;
|
| 251 |
-
flex-wrap: nowrap !important;
|
| 252 |
-
gap: 24px !important;
|
| 253 |
-
align-items: flex-start !important;
|
| 254 |
-
}
|
| 255 |
-
|
| 256 |
-
/* Input section - fixed width */
|
| 257 |
-
#input-column {
|
| 258 |
-
background: #ffffff !important;
|
| 259 |
-
border-radius: 18px !important;
|
| 260 |
-
padding: 32px !important;
|
| 261 |
-
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08) !important;
|
| 262 |
-
width: 550px !important;
|
| 263 |
-
min-width: 550px !important;
|
| 264 |
-
max-width: 550px !important;
|
| 265 |
-
flex: 0 0 550px !important;
|
| 266 |
}
|
| 267 |
|
| 268 |
-
|
| 269 |
-
|
| 270 |
-
|
| 271 |
-
min-height: 80vh !important;
|
| 272 |
-
max-height: 90vh !important;
|
| 273 |
-
display: flex !important;
|
| 274 |
-
flex-direction: column !important;
|
| 275 |
}
|
| 276 |
|
| 277 |
-
/* Header
|
| 278 |
.header-container {
|
| 279 |
-
text-align:
|
| 280 |
margin-bottom: 24px;
|
| 281 |
}
|
| 282 |
|
|
@@ -284,20 +267,45 @@ css = """
|
|
| 284 |
font-size: 32px !important;
|
| 285 |
font-weight: 600 !important;
|
| 286 |
letter-spacing: -0.02em !important;
|
|
|
|
| 287 |
color: #1d1d1f !important;
|
| 288 |
-
margin: 0 !important;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 289 |
}
|
| 290 |
|
| 291 |
-
/*
|
| 292 |
#prompt-textbox textarea {
|
| 293 |
-
|
| 294 |
-
|
| 295 |
border-radius: 12px !important;
|
| 296 |
border: 1px solid #d2d2d7 !important;
|
| 297 |
-
padding: 16px !important;
|
| 298 |
-
|
| 299 |
-
|
|
|
|
|
|
|
|
|
|
| 300 |
resize: vertical !important;
|
|
|
|
|
|
|
| 301 |
}
|
| 302 |
|
| 303 |
#prompt-textbox textarea:focus {
|
|
@@ -323,47 +331,53 @@ css = """
|
|
| 323 |
color: #ff3b30;
|
| 324 |
}
|
| 325 |
|
| 326 |
-
/*
|
| 327 |
button.primary {
|
|
|
|
|
|
|
|
|
|
|
|
|
| 328 |
background: #0071e3 !important;
|
| 329 |
border: none !important;
|
| 330 |
-
|
| 331 |
-
|
| 332 |
-
|
| 333 |
-
font-weight: 500 !important;
|
| 334 |
-
color: white !important;
|
| 335 |
cursor: pointer !important;
|
| 336 |
-
transition: all 0.2s ease !important;
|
| 337 |
width: 100% !important;
|
| 338 |
margin-top: 16px !important;
|
| 339 |
}
|
| 340 |
|
| 341 |
button.primary:hover {
|
| 342 |
-
background: #
|
| 343 |
-
transform: scale(1.02) !important;
|
| 344 |
}
|
| 345 |
|
| 346 |
-
/*
|
| 347 |
-
|
| 348 |
-
|
| 349 |
-
border-radius:
|
| 350 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 351 |
}
|
| 352 |
|
| 353 |
-
|
| 354 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 355 |
object-fit: contain !important;
|
| 356 |
}
|
| 357 |
|
| 358 |
-
/*
|
| 359 |
-
#
|
| 360 |
-
|
| 361 |
-
overflow: hidden !important;
|
| 362 |
-
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08) !important;
|
| 363 |
-
}
|
| 364 |
-
|
| 365 |
-
/* Dark mode support */
|
| 366 |
-
.dark #input-column {
|
| 367 |
background: #1d1d1f !important;
|
| 368 |
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.4) !important;
|
| 369 |
}
|
|
@@ -373,19 +387,52 @@ button.primary:hover {
|
|
| 373 |
}
|
| 374 |
|
| 375 |
.dark #prompt-textbox textarea {
|
| 376 |
-
background: #
|
| 377 |
border-color: #424245 !important;
|
| 378 |
color: #f5f5f7 !important;
|
| 379 |
}
|
| 380 |
|
| 381 |
-
.dark #prompt-textbox textarea:focus {
|
| 382 |
-
border-color: #0071e3 !important;
|
| 383 |
-
}
|
| 384 |
-
|
| 385 |
.dark .char-counter {
|
| 386 |
color: #a1a1a6 !important;
|
| 387 |
}
|
| 388 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 389 |
/* Responsive adjustments */
|
| 390 |
@media (max-width: 1200px) {
|
| 391 |
#main-row {
|
|
@@ -407,69 +454,82 @@ button.primary:hover {
|
|
| 407 |
}
|
| 408 |
"""
|
| 409 |
|
| 410 |
-
# JavaScript for layout control and character counter
|
| 411 |
js_code = """
|
| 412 |
function() {
|
| 413 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 414 |
function forceHorizontalLayout() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 415 |
const mainRow = document.getElementById('main-row');
|
| 416 |
if (mainRow) {
|
| 417 |
-
mainRow.style.display = 'flex';
|
| 418 |
mainRow.style.flexDirection = 'row';
|
| 419 |
mainRow.style.flexWrap = 'nowrap';
|
|
|
|
|
|
|
| 420 |
}
|
| 421 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 422 |
const inputCol = document.getElementById('input-column');
|
| 423 |
if (inputCol) {
|
| 424 |
-
inputCol.style.flex = '0 0 550px';
|
| 425 |
inputCol.style.width = '550px';
|
| 426 |
inputCol.style.minWidth = '550px';
|
| 427 |
inputCol.style.maxWidth = '550px';
|
|
|
|
| 428 |
}
|
| 429 |
|
| 430 |
const outputCol = document.getElementById('output-column');
|
| 431 |
if (outputCol) {
|
| 432 |
outputCol.style.flex = '1 1 auto';
|
|
|
|
| 433 |
}
|
| 434 |
}
|
| 435 |
|
| 436 |
-
// Character counter setup
|
| 437 |
-
function setupCharCounter() {
|
| 438 |
-
const textbox = document.querySelector('#prompt-textbox textarea');
|
| 439 |
-
const counterDiv = document.querySelector('.char-counter');
|
| 440 |
-
const countSpan = document.getElementById('char-count');
|
| 441 |
-
|
| 442 |
-
if (textbox && countSpan && counterDiv) {
|
| 443 |
-
const updateCounter = () => {
|
| 444 |
-
const len = textbox.value.length;
|
| 445 |
-
countSpan.textContent = len;
|
| 446 |
-
|
| 447 |
-
counterDiv.classList.remove('warning', 'limit');
|
| 448 |
-
if (len >= 2000) {
|
| 449 |
-
counterDiv.classList.add('limit');
|
| 450 |
-
} else if (len >= 1800) {
|
| 451 |
-
counterDiv.classList.add('warning');
|
| 452 |
-
}
|
| 453 |
-
};
|
| 454 |
-
|
| 455 |
-
textbox.addEventListener('input', updateCounter);
|
| 456 |
-
updateCounter();
|
| 457 |
-
}
|
| 458 |
-
}
|
| 459 |
-
|
| 460 |
-
// Run on load and with slight delay for Gradio rendering
|
| 461 |
forceHorizontalLayout();
|
| 462 |
setupCharCounter();
|
| 463 |
|
| 464 |
-
setTimeout(
|
| 465 |
-
|
| 466 |
-
|
| 467 |
-
|
| 468 |
|
| 469 |
-
setTimeout(
|
| 470 |
-
|
| 471 |
-
|
| 472 |
-
|
|
|
|
| 473 |
}
|
| 474 |
"""
|
| 475 |
|
|
@@ -526,35 +586,6 @@ with gr.Blocks() as demo:
|
|
| 526 |
container=True,
|
| 527 |
)
|
| 528 |
|
| 529 |
-
# Advanced Settings accordion
|
| 530 |
-
with gr.Accordion("Advanced Settings", open=False):
|
| 531 |
-
seed = gr.Slider(
|
| 532 |
-
label="Seed",
|
| 533 |
-
minimum=0,
|
| 534 |
-
maximum=MAX_SEED,
|
| 535 |
-
step=1,
|
| 536 |
-
value=0,
|
| 537 |
-
)
|
| 538 |
-
|
| 539 |
-
randomize_seed = gr.Checkbox(label="Randomize seed", value=True)
|
| 540 |
-
|
| 541 |
-
with gr.Row():
|
| 542 |
-
num_inference_steps = gr.Slider(
|
| 543 |
-
label="Number of inference steps",
|
| 544 |
-
minimum=1,
|
| 545 |
-
maximum=100,
|
| 546 |
-
step=1,
|
| 547 |
-
value=30,
|
| 548 |
-
)
|
| 549 |
-
|
| 550 |
-
guidance_scale = gr.Slider(
|
| 551 |
-
label="Guidance scale",
|
| 552 |
-
minimum=0.0,
|
| 553 |
-
maximum=10.0,
|
| 554 |
-
step=0.1,
|
| 555 |
-
value=4,
|
| 556 |
-
)
|
| 557 |
-
|
| 558 |
# Generate Button
|
| 559 |
generate_btn = gr.Button(
|
| 560 |
"Generate",
|
|
@@ -576,8 +607,8 @@ with gr.Blocks() as demo:
|
|
| 576 |
gr.on(
|
| 577 |
triggers=[generate_btn.click, prompt.submit],
|
| 578 |
fn=infer,
|
| 579 |
-
inputs=[prompt, aspect_ratio
|
| 580 |
-
outputs=[result
|
| 581 |
show_progress="full"
|
| 582 |
)
|
| 583 |
|
|
|
|
| 196 |
return int(match.group(1)), int(match.group(2))
|
| 197 |
return 1024, 1024 # Default
|
| 198 |
|
| 199 |
+
def infer(prompt, aspect_ratio="2:3 (1344x2048)", progress=gr.Progress(track_tqdm=True)):
|
| 200 |
+
"""Generate an image using FLUX.2 model."""
|
| 201 |
+
if not prompt.strip():
|
| 202 |
+
raise gr.Error("Please enter a prompt to generate an image.")
|
| 203 |
|
| 204 |
+
# Always use random seed
|
| 205 |
+
seed = random.randint(0, MAX_SEED)
|
| 206 |
|
| 207 |
# Parse aspect ratio to get width and height
|
| 208 |
width, height = parse_aspect_ratio(aspect_ratio)
|
| 209 |
|
| 210 |
+
# Fixed inference parameters
|
| 211 |
+
num_inference_steps = 30
|
| 212 |
+
guidance_scale = 4.0
|
| 213 |
+
|
| 214 |
# Text Encoding (Network bound - No GPU needed)
|
| 215 |
progress(0.1, desc="Encoding prompt...")
|
| 216 |
prompt_embeds = remote_text_encoder(prompt)
|
| 217 |
|
| 218 |
# Image Generation (GPU bound)
|
| 219 |
+
progress(0.3, desc="Generating image...")
|
| 220 |
image = generate_image(
|
| 221 |
prompt_embeds,
|
| 222 |
None, # No input images
|
|
|
|
| 228 |
progress
|
| 229 |
)
|
| 230 |
|
| 231 |
+
return image
|
| 232 |
|
| 233 |
examples = [
|
| 234 |
["Create a vase on a table in living room, the color of the vase is a gradient of color, starting with #02eb3c color and finishing with #edfa3c. The flowers inside the vase have the color #ff0088"],
|
|
|
|
| 242 |
["The person from image 1 is petting the cat from image 2, the bird from image 3 is next to them", ["woman1.webp", "cat_window.webp", "bird.webp"]]
|
| 243 |
]
|
| 244 |
|
| 245 |
+
# Apple-inspired CSS styling (matching Z-Image)
|
| 246 |
css = """
|
| 247 |
+
/* Global Styles */
|
| 248 |
.gradio-container {
|
| 249 |
max-width: 85vw !important;
|
| 250 |
margin: 0 auto !important;
|
| 251 |
+
padding: 48px 20px !important;
|
| 252 |
+
font-family: -apple-system, BlinkMacSystemFont, 'Inter', 'Segoe UI', 'Roboto', sans-serif !important;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 253 |
}
|
| 254 |
|
| 255 |
+
* {
|
| 256 |
+
transition: none !important;
|
| 257 |
+
animation: none !important;
|
|
|
|
|
|
|
|
|
|
|
|
|
| 258 |
}
|
| 259 |
|
| 260 |
+
/* Header */
|
| 261 |
.header-container {
|
| 262 |
+
text-align: left;
|
| 263 |
margin-bottom: 24px;
|
| 264 |
}
|
| 265 |
|
|
|
|
| 267 |
font-size: 32px !important;
|
| 268 |
font-weight: 600 !important;
|
| 269 |
letter-spacing: -0.02em !important;
|
| 270 |
+
line-height: 1.07 !important;
|
| 271 |
color: #1d1d1f !important;
|
| 272 |
+
margin: 0 0 16px 0 !important;
|
| 273 |
+
}
|
| 274 |
+
|
| 275 |
+
/* Input Section */
|
| 276 |
+
.input-section {
|
| 277 |
+
background: #ffffff;
|
| 278 |
+
border-radius: 18px;
|
| 279 |
+
padding: 32px;
|
| 280 |
+
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
|
| 281 |
+
}
|
| 282 |
+
|
| 283 |
+
#input-column {
|
| 284 |
+
background: #ffffff !important;
|
| 285 |
+
border-radius: 18px !important;
|
| 286 |
+
padding: 32px !important;
|
| 287 |
+
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08) !important;
|
| 288 |
+
width: 550px !important;
|
| 289 |
+
min-width: 550px !important;
|
| 290 |
+
max-width: 550px !important;
|
| 291 |
+
flex: 0 0 550px !important;
|
| 292 |
}
|
| 293 |
|
| 294 |
+
/* Textbox */
|
| 295 |
#prompt-textbox textarea {
|
| 296 |
+
font-size: 17px !important;
|
| 297 |
+
line-height: 1.47 !important;
|
| 298 |
border-radius: 12px !important;
|
| 299 |
border: 1px solid #d2d2d7 !important;
|
| 300 |
+
padding: 12px 16px !important;
|
| 301 |
+
background: #ffffff !important;
|
| 302 |
+
font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif !important;
|
| 303 |
+
min-height: 500px !important;
|
| 304 |
+
max-height: 700px !important;
|
| 305 |
+
height: 500px !important;
|
| 306 |
resize: vertical !important;
|
| 307 |
+
overflow-y: auto !important;
|
| 308 |
+
margin-bottom: 16px !important;
|
| 309 |
}
|
| 310 |
|
| 311 |
#prompt-textbox textarea:focus {
|
|
|
|
| 331 |
color: #ff3b30;
|
| 332 |
}
|
| 333 |
|
| 334 |
+
/* Button */
|
| 335 |
button.primary {
|
| 336 |
+
font-size: 17px !important;
|
| 337 |
+
font-weight: 400 !important;
|
| 338 |
+
padding: 12px 32px !important;
|
| 339 |
+
border-radius: 980px !important;
|
| 340 |
background: #0071e3 !important;
|
| 341 |
border: none !important;
|
| 342 |
+
color: #ffffff !important;
|
| 343 |
+
min-height: 44px !important;
|
| 344 |
+
letter-spacing: -0.01em !important;
|
|
|
|
|
|
|
| 345 |
cursor: pointer !important;
|
|
|
|
| 346 |
width: 100% !important;
|
| 347 |
margin-top: 16px !important;
|
| 348 |
}
|
| 349 |
|
| 350 |
button.primary:hover {
|
| 351 |
+
background: #0077ed !important;
|
|
|
|
| 352 |
}
|
| 353 |
|
| 354 |
+
/* Output Section */
|
| 355 |
+
#output-column {
|
| 356 |
+
background: #ffffff !important;
|
| 357 |
+
border-radius: 18px !important;
|
| 358 |
+
padding: 32px !important;
|
| 359 |
+
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08) !important;
|
| 360 |
+
overflow: hidden !important;
|
| 361 |
+
display: flex !important;
|
| 362 |
+
align-items: center !important;
|
| 363 |
+
justify-content: center !important;
|
| 364 |
+
min-height: 80vh !important;
|
| 365 |
+
max-height: 90vh !important;
|
| 366 |
+
flex: 1 1 auto !important;
|
| 367 |
}
|
| 368 |
|
| 369 |
+
#output-column img {
|
| 370 |
+
border-radius: 12px !important;
|
| 371 |
+
max-width: 100% !important;
|
| 372 |
+
max-height: 85vh !important;
|
| 373 |
+
width: auto !important;
|
| 374 |
+
height: auto !important;
|
| 375 |
object-fit: contain !important;
|
| 376 |
}
|
| 377 |
|
| 378 |
+
/* Dark Mode */
|
| 379 |
+
.dark #input-column,
|
| 380 |
+
.dark #output-column {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 381 |
background: #1d1d1f !important;
|
| 382 |
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.4) !important;
|
| 383 |
}
|
|
|
|
| 387 |
}
|
| 388 |
|
| 389 |
.dark #prompt-textbox textarea {
|
| 390 |
+
background: #1d1d1f !important;
|
| 391 |
border-color: #424245 !important;
|
| 392 |
color: #f5f5f7 !important;
|
| 393 |
}
|
| 394 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 395 |
.dark .char-counter {
|
| 396 |
color: #a1a1a6 !important;
|
| 397 |
}
|
| 398 |
|
| 399 |
+
/* Layout - Force horizontal layout */
|
| 400 |
+
#main-row {
|
| 401 |
+
align-items: flex-start !important;
|
| 402 |
+
flex-direction: row !important;
|
| 403 |
+
display: flex !important;
|
| 404 |
+
flex-wrap: nowrap !important;
|
| 405 |
+
width: 100% !important;
|
| 406 |
+
gap: 24px !important;
|
| 407 |
+
}
|
| 408 |
+
|
| 409 |
+
.gradio-row {
|
| 410 |
+
align-items: flex-start !important;
|
| 411 |
+
flex-direction: row !important;
|
| 412 |
+
display: flex !important;
|
| 413 |
+
flex-wrap: nowrap !important;
|
| 414 |
+
width: 100% !important;
|
| 415 |
+
}
|
| 416 |
+
|
| 417 |
+
.gradio-row > .gradio-column:first-child,
|
| 418 |
+
.gradio-row > div:first-child {
|
| 419 |
+
width: 550px !important;
|
| 420 |
+
min-width: 550px !important;
|
| 421 |
+
max-width: 550px !important;
|
| 422 |
+
flex: 0 0 550px !important;
|
| 423 |
+
}
|
| 424 |
+
|
| 425 |
+
.gradio-row > .gradio-column:last-child,
|
| 426 |
+
.gradio-row > div:last-child {
|
| 427 |
+
flex: 1 1 auto !important;
|
| 428 |
+
min-width: 0 !important;
|
| 429 |
+
}
|
| 430 |
+
|
| 431 |
+
/* Hide footer */
|
| 432 |
+
footer {
|
| 433 |
+
display: none !important;
|
| 434 |
+
}
|
| 435 |
+
|
| 436 |
/* Responsive adjustments */
|
| 437 |
@media (max-width: 1200px) {
|
| 438 |
#main-row {
|
|
|
|
| 454 |
}
|
| 455 |
"""
|
| 456 |
|
| 457 |
+
# JavaScript for layout control and character counter (matching Z-Image)
|
| 458 |
js_code = """
|
| 459 |
function() {
|
| 460 |
+
function setupCharCounter() {
|
| 461 |
+
const textbox = document.querySelector('#prompt-textbox textarea');
|
| 462 |
+
const counter = document.querySelector('.char-counter');
|
| 463 |
+
const countSpan = document.getElementById('char-count');
|
| 464 |
+
|
| 465 |
+
if (textbox && counter && countSpan) {
|
| 466 |
+
function updateCount() {
|
| 467 |
+
const len = textbox.value.length;
|
| 468 |
+
countSpan.textContent = len;
|
| 469 |
+
|
| 470 |
+
counter.classList.remove('warning', 'limit');
|
| 471 |
+
if (len >= 2000) {
|
| 472 |
+
counter.classList.add('limit');
|
| 473 |
+
} else if (len >= 1800) {
|
| 474 |
+
counter.classList.add('warning');
|
| 475 |
+
}
|
| 476 |
+
}
|
| 477 |
+
|
| 478 |
+
textbox.addEventListener('input', updateCount);
|
| 479 |
+
updateCount();
|
| 480 |
+
}
|
| 481 |
+
}
|
| 482 |
+
|
| 483 |
function forceHorizontalLayout() {
|
| 484 |
+
const container = document.querySelector('.gradio-container');
|
| 485 |
+
if (container) {
|
| 486 |
+
container.style.maxWidth = '85vw';
|
| 487 |
+
container.style.width = '85vw';
|
| 488 |
+
}
|
| 489 |
+
|
| 490 |
const mainRow = document.getElementById('main-row');
|
| 491 |
if (mainRow) {
|
|
|
|
| 492 |
mainRow.style.flexDirection = 'row';
|
| 493 |
mainRow.style.flexWrap = 'nowrap';
|
| 494 |
+
mainRow.style.display = 'flex';
|
| 495 |
+
mainRow.style.width = '100%';
|
| 496 |
}
|
| 497 |
|
| 498 |
+
const rows = document.querySelectorAll('.gradio-row');
|
| 499 |
+
rows.forEach(row => {
|
| 500 |
+
row.style.flexDirection = 'row';
|
| 501 |
+
row.style.flexWrap = 'nowrap';
|
| 502 |
+
row.style.display = 'flex';
|
| 503 |
+
});
|
| 504 |
+
|
| 505 |
const inputCol = document.getElementById('input-column');
|
| 506 |
if (inputCol) {
|
|
|
|
| 507 |
inputCol.style.width = '550px';
|
| 508 |
inputCol.style.minWidth = '550px';
|
| 509 |
inputCol.style.maxWidth = '550px';
|
| 510 |
+
inputCol.style.flex = '0 0 550px';
|
| 511 |
}
|
| 512 |
|
| 513 |
const outputCol = document.getElementById('output-column');
|
| 514 |
if (outputCol) {
|
| 515 |
outputCol.style.flex = '1 1 auto';
|
| 516 |
+
outputCol.style.minWidth = '0';
|
| 517 |
}
|
| 518 |
}
|
| 519 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 520 |
forceHorizontalLayout();
|
| 521 |
setupCharCounter();
|
| 522 |
|
| 523 |
+
setTimeout(forceHorizontalLayout, 100);
|
| 524 |
+
setTimeout(forceHorizontalLayout, 500);
|
| 525 |
+
setTimeout(forceHorizontalLayout, 1000);
|
| 526 |
+
setTimeout(forceHorizontalLayout, 2000);
|
| 527 |
|
| 528 |
+
setTimeout(setupCharCounter, 100);
|
| 529 |
+
setTimeout(setupCharCounter, 500);
|
| 530 |
+
|
| 531 |
+
const observer = new MutationObserver(forceHorizontalLayout);
|
| 532 |
+
observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });
|
| 533 |
}
|
| 534 |
"""
|
| 535 |
|
|
|
|
| 586 |
container=True,
|
| 587 |
)
|
| 588 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 589 |
# Generate Button
|
| 590 |
generate_btn = gr.Button(
|
| 591 |
"Generate",
|
|
|
|
| 607 |
gr.on(
|
| 608 |
triggers=[generate_btn.click, prompt.submit],
|
| 609 |
fn=infer,
|
| 610 |
+
inputs=[prompt, aspect_ratio],
|
| 611 |
+
outputs=[result],
|
| 612 |
show_progress="full"
|
| 613 |
)
|
| 614 |
|