Spaces:
Running
Running
update theme
Browse files
app.py
CHANGED
|
@@ -2352,19 +2352,281 @@ def load_project_from_url(url: str) -> Tuple[str, str]:
|
|
| 2352 |
|
| 2353 |
return f"✅ Successfully imported project from {username}/{project_name}", code_content
|
| 2354 |
|
| 2355 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2356 |
with gr.Blocks(
|
| 2357 |
-
|
| 2358 |
-
|
| 2359 |
-
|
| 2360 |
-
|
| 2361 |
-
|
| 2362 |
-
|
| 2363 |
-
|
| 2364 |
-
|
| 2365 |
-
|
| 2366 |
-
|
| 2367 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2368 |
) as demo:
|
| 2369 |
history = gr.State([])
|
| 2370 |
setting = gr.State({
|
|
@@ -2377,6 +2639,18 @@ with gr.Blocks(
|
|
| 2377 |
with gr.Sidebar():
|
| 2378 |
login_button = gr.LoginButton()
|
| 2379 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2380 |
# Add Load Project section
|
| 2381 |
gr.Markdown("📥 Load Existing Project")
|
| 2382 |
load_project_url = gr.Textbox(
|
|
@@ -2640,6 +2914,55 @@ with gr.Blocks(
|
|
| 2640 |
outputs=[space_name_input, deploy_btn]
|
| 2641 |
)
|
| 2642 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2643 |
# Deploy to Spaces logic
|
| 2644 |
|
| 2645 |
def deploy_to_user_space(
|
|
|
|
| 2352 |
|
| 2353 |
return f"✅ Successfully imported project from {username}/{project_name}", code_content
|
| 2354 |
|
| 2355 |
+
# Gradio Theme Configurations with proper theme objects
|
| 2356 |
+
def get_saved_theme():
|
| 2357 |
+
"""Get the saved theme preference from file"""
|
| 2358 |
+
try:
|
| 2359 |
+
if os.path.exists('.theme_preference'):
|
| 2360 |
+
with open('.theme_preference', 'r') as f:
|
| 2361 |
+
return f.read().strip()
|
| 2362 |
+
except:
|
| 2363 |
+
pass
|
| 2364 |
+
return "Developer"
|
| 2365 |
+
|
| 2366 |
+
def save_theme_preference(theme_name):
|
| 2367 |
+
"""Save theme preference to file"""
|
| 2368 |
+
try:
|
| 2369 |
+
with open('.theme_preference', 'w') as f:
|
| 2370 |
+
f.write(theme_name)
|
| 2371 |
+
except:
|
| 2372 |
+
pass
|
| 2373 |
+
|
| 2374 |
+
THEME_CONFIGS = {
|
| 2375 |
+
"Default": {
|
| 2376 |
+
"theme": gr.themes.Default(),
|
| 2377 |
+
"description": "Gradio's standard theme with clean orange accents"
|
| 2378 |
+
},
|
| 2379 |
+
"Base": {
|
| 2380 |
+
"theme": gr.themes.Base(
|
| 2381 |
+
primary_hue="blue",
|
| 2382 |
+
secondary_hue="slate",
|
| 2383 |
+
neutral_hue="slate",
|
| 2384 |
+
text_size="sm",
|
| 2385 |
+
spacing_size="sm",
|
| 2386 |
+
radius_size="md"
|
| 2387 |
+
),
|
| 2388 |
+
"description": "Minimal foundation theme with blue accents"
|
| 2389 |
+
},
|
| 2390 |
+
"Soft": {
|
| 2391 |
+
"theme": gr.themes.Soft(
|
| 2392 |
+
primary_hue="emerald",
|
| 2393 |
+
secondary_hue="emerald",
|
| 2394 |
+
neutral_hue="slate",
|
| 2395 |
+
text_size="sm",
|
| 2396 |
+
spacing_size="md",
|
| 2397 |
+
radius_size="lg"
|
| 2398 |
+
),
|
| 2399 |
+
"description": "Gentle rounded theme with soft emerald colors"
|
| 2400 |
+
},
|
| 2401 |
+
"Monochrome": {
|
| 2402 |
+
"theme": gr.themes.Monochrome(
|
| 2403 |
+
primary_hue="slate",
|
| 2404 |
+
secondary_hue="slate",
|
| 2405 |
+
neutral_hue="slate",
|
| 2406 |
+
text_size="sm",
|
| 2407 |
+
spacing_size="sm",
|
| 2408 |
+
radius_size="sm"
|
| 2409 |
+
),
|
| 2410 |
+
"description": "Elegant black and white design"
|
| 2411 |
+
},
|
| 2412 |
+
"Glass": {
|
| 2413 |
+
"theme": gr.themes.Glass(
|
| 2414 |
+
primary_hue="blue",
|
| 2415 |
+
secondary_hue="blue",
|
| 2416 |
+
neutral_hue="slate",
|
| 2417 |
+
text_size="sm",
|
| 2418 |
+
spacing_size="md",
|
| 2419 |
+
radius_size="lg"
|
| 2420 |
+
),
|
| 2421 |
+
"description": "Modern glassmorphism with blur effects"
|
| 2422 |
+
},
|
| 2423 |
+
"Dark Ocean": {
|
| 2424 |
+
"theme": gr.themes.Base(
|
| 2425 |
+
primary_hue="blue",
|
| 2426 |
+
secondary_hue="slate",
|
| 2427 |
+
neutral_hue="slate",
|
| 2428 |
+
text_size="sm",
|
| 2429 |
+
spacing_size="sm",
|
| 2430 |
+
radius_size="md"
|
| 2431 |
+
).set(
|
| 2432 |
+
body_background_fill="#0f172a",
|
| 2433 |
+
body_background_fill_dark="#0f172a",
|
| 2434 |
+
background_fill_primary="#3b82f6",
|
| 2435 |
+
background_fill_secondary="#1e293b",
|
| 2436 |
+
border_color_primary="#334155",
|
| 2437 |
+
block_background_fill="#1e293b",
|
| 2438 |
+
block_border_color="#334155",
|
| 2439 |
+
body_text_color="#f1f5f9",
|
| 2440 |
+
body_text_color_dark="#f1f5f9",
|
| 2441 |
+
block_label_text_color="#f1f5f9",
|
| 2442 |
+
block_label_text_color_dark="#f1f5f9",
|
| 2443 |
+
block_title_text_color="#f1f5f9",
|
| 2444 |
+
block_title_text_color_dark="#f1f5f9",
|
| 2445 |
+
input_background_fill="#0f172a",
|
| 2446 |
+
input_background_fill_dark="#0f172a",
|
| 2447 |
+
input_border_color="#334155",
|
| 2448 |
+
input_border_color_dark="#334155",
|
| 2449 |
+
button_primary_background_fill="#3b82f6",
|
| 2450 |
+
button_primary_border_color="#3b82f6",
|
| 2451 |
+
button_secondary_background_fill="#334155",
|
| 2452 |
+
button_secondary_border_color="#475569"
|
| 2453 |
+
),
|
| 2454 |
+
"description": "Deep blue dark theme perfect for coding"
|
| 2455 |
+
},
|
| 2456 |
+
"Cyberpunk": {
|
| 2457 |
+
"theme": gr.themes.Base(
|
| 2458 |
+
primary_hue="fuchsia",
|
| 2459 |
+
secondary_hue="cyan",
|
| 2460 |
+
neutral_hue="slate",
|
| 2461 |
+
text_size="sm",
|
| 2462 |
+
spacing_size="sm",
|
| 2463 |
+
radius_size="none",
|
| 2464 |
+
font=["Orbitron", "Courier New", "monospace"]
|
| 2465 |
+
).set(
|
| 2466 |
+
body_background_fill="#0a0a0f",
|
| 2467 |
+
body_background_fill_dark="#0a0a0f",
|
| 2468 |
+
background_fill_primary="#ff10f0",
|
| 2469 |
+
background_fill_secondary="#1a1a2e",
|
| 2470 |
+
border_color_primary="#00f5ff",
|
| 2471 |
+
block_background_fill="#1a1a2e",
|
| 2472 |
+
block_border_color="#00f5ff",
|
| 2473 |
+
body_text_color="#00f5ff",
|
| 2474 |
+
body_text_color_dark="#00f5ff",
|
| 2475 |
+
block_label_text_color="#ff10f0",
|
| 2476 |
+
block_label_text_color_dark="#ff10f0",
|
| 2477 |
+
block_title_text_color="#ff10f0",
|
| 2478 |
+
block_title_text_color_dark="#ff10f0",
|
| 2479 |
+
input_background_fill="#0a0a0f",
|
| 2480 |
+
input_background_fill_dark="#0a0a0f",
|
| 2481 |
+
input_border_color="#00f5ff",
|
| 2482 |
+
input_border_color_dark="#00f5ff",
|
| 2483 |
+
button_primary_background_fill="#ff10f0",
|
| 2484 |
+
button_primary_border_color="#ff10f0",
|
| 2485 |
+
button_secondary_background_fill="#1a1a2e",
|
| 2486 |
+
button_secondary_border_color="#00f5ff"
|
| 2487 |
+
),
|
| 2488 |
+
"description": "Futuristic neon cyber aesthetics"
|
| 2489 |
+
},
|
| 2490 |
+
"Forest": {
|
| 2491 |
+
"theme": gr.themes.Soft(
|
| 2492 |
+
primary_hue="emerald",
|
| 2493 |
+
secondary_hue="green",
|
| 2494 |
+
neutral_hue="emerald",
|
| 2495 |
+
text_size="sm",
|
| 2496 |
+
spacing_size="md",
|
| 2497 |
+
radius_size="lg"
|
| 2498 |
+
).set(
|
| 2499 |
+
body_background_fill="#f0fdf4",
|
| 2500 |
+
body_background_fill_dark="#064e3b",
|
| 2501 |
+
background_fill_primary="#059669",
|
| 2502 |
+
background_fill_secondary="#ecfdf5",
|
| 2503 |
+
border_color_primary="#bbf7d0",
|
| 2504 |
+
block_background_fill="#ffffff",
|
| 2505 |
+
block_border_color="#d1fae5",
|
| 2506 |
+
body_text_color="#064e3b",
|
| 2507 |
+
body_text_color_dark="#f0fdf4",
|
| 2508 |
+
block_label_text_color="#064e3b",
|
| 2509 |
+
block_label_text_color_dark="#f0fdf4",
|
| 2510 |
+
block_title_text_color="#059669",
|
| 2511 |
+
block_title_text_color_dark="#10b981"
|
| 2512 |
+
),
|
| 2513 |
+
"description": "Nature-inspired green earth tones"
|
| 2514 |
+
},
|
| 2515 |
+
"High Contrast": {
|
| 2516 |
+
"theme": gr.themes.Base(
|
| 2517 |
+
primary_hue="yellow",
|
| 2518 |
+
secondary_hue="slate",
|
| 2519 |
+
neutral_hue="slate",
|
| 2520 |
+
text_size="lg",
|
| 2521 |
+
spacing_size="lg",
|
| 2522 |
+
radius_size="sm"
|
| 2523 |
+
).set(
|
| 2524 |
+
body_background_fill="#ffffff",
|
| 2525 |
+
body_background_fill_dark="#ffffff",
|
| 2526 |
+
background_fill_primary="#000000",
|
| 2527 |
+
background_fill_secondary="#ffffff",
|
| 2528 |
+
border_color_primary="#000000",
|
| 2529 |
+
block_background_fill="#ffffff",
|
| 2530 |
+
block_border_color="#000000",
|
| 2531 |
+
body_text_color="#000000",
|
| 2532 |
+
body_text_color_dark="#000000",
|
| 2533 |
+
block_label_text_color="#000000",
|
| 2534 |
+
block_label_text_color_dark="#000000",
|
| 2535 |
+
block_title_text_color="#000000",
|
| 2536 |
+
block_title_text_color_dark="#000000",
|
| 2537 |
+
input_background_fill="#ffffff",
|
| 2538 |
+
input_background_fill_dark="#ffffff",
|
| 2539 |
+
input_border_color="#000000",
|
| 2540 |
+
input_border_color_dark="#000000",
|
| 2541 |
+
button_primary_background_fill="#ffff00",
|
| 2542 |
+
button_primary_border_color="#000000",
|
| 2543 |
+
button_secondary_background_fill="#ffffff",
|
| 2544 |
+
button_secondary_border_color="#000000"
|
| 2545 |
+
),
|
| 2546 |
+
"description": "Accessibility-focused high visibility"
|
| 2547 |
+
},
|
| 2548 |
+
"Developer": {
|
| 2549 |
+
"theme": gr.themes.Base(
|
| 2550 |
+
primary_hue="blue",
|
| 2551 |
+
secondary_hue="slate",
|
| 2552 |
+
neutral_hue="slate",
|
| 2553 |
+
text_size="sm",
|
| 2554 |
+
spacing_size="sm",
|
| 2555 |
+
radius_size="sm",
|
| 2556 |
+
font=["Consolas", "Monaco", "Courier New", "monospace"]
|
| 2557 |
+
).set(
|
| 2558 |
+
# VS Code exact colors
|
| 2559 |
+
body_background_fill="#1e1e1e", # VS Code editor background
|
| 2560 |
+
body_background_fill_dark="#1e1e1e",
|
| 2561 |
+
background_fill_primary="#007acc", # VS Code blue accent
|
| 2562 |
+
background_fill_secondary="#252526", # VS Code sidebar background
|
| 2563 |
+
border_color_primary="#3e3e42", # VS Code border color
|
| 2564 |
+
block_background_fill="#252526", # VS Code panel background
|
| 2565 |
+
block_border_color="#3e3e42", # VS Code subtle borders
|
| 2566 |
+
body_text_color="#cccccc", # VS Code default text
|
| 2567 |
+
body_text_color_dark="#cccccc",
|
| 2568 |
+
block_label_text_color="#cccccc",
|
| 2569 |
+
block_label_text_color_dark="#cccccc",
|
| 2570 |
+
block_title_text_color="#ffffff", # VS Code active text
|
| 2571 |
+
block_title_text_color_dark="#ffffff",
|
| 2572 |
+
input_background_fill="#2d2d30", # VS Code input background
|
| 2573 |
+
input_background_fill_dark="#2d2d30",
|
| 2574 |
+
input_border_color="#3e3e42", # VS Code input border
|
| 2575 |
+
input_border_color_dark="#3e3e42",
|
| 2576 |
+
input_border_color_focus="#007acc", # VS Code focus border
|
| 2577 |
+
input_border_color_focus_dark="#007acc",
|
| 2578 |
+
button_primary_background_fill="#007acc", # VS Code button blue
|
| 2579 |
+
button_primary_border_color="#007acc",
|
| 2580 |
+
button_primary_background_fill_hover="#0e639c", # VS Code button hover
|
| 2581 |
+
button_secondary_background_fill="#2d2d30",
|
| 2582 |
+
button_secondary_border_color="#3e3e42",
|
| 2583 |
+
button_secondary_text_color="#cccccc"
|
| 2584 |
+
),
|
| 2585 |
+
"description": "Authentic VS Code dark theme with exact color matching"
|
| 2586 |
+
}
|
| 2587 |
+
}
|
| 2588 |
+
|
| 2589 |
+
# Additional theme information for developers
|
| 2590 |
+
THEME_FEATURES = {
|
| 2591 |
+
"Default": ["Orange accents", "Clean layout", "Standard Gradio look"],
|
| 2592 |
+
"Base": ["Blue accents", "Minimal styling", "Clean foundation"],
|
| 2593 |
+
"Soft": ["Rounded corners", "Emerald colors", "Comfortable viewing"],
|
| 2594 |
+
"Monochrome": ["Black & white", "High elegance", "Timeless design"],
|
| 2595 |
+
"Glass": ["Glassmorphism", "Blur effects", "Translucent elements"],
|
| 2596 |
+
"Dark Ocean": ["Deep blue palette", "Dark theme", "Easy on eyes"],
|
| 2597 |
+
"Cyberpunk": ["Neon cyan/magenta", "Futuristic fonts", "Cyber vibes"],
|
| 2598 |
+
"Forest": ["Nature inspired", "Green tones", "Organic rounded"],
|
| 2599 |
+
"High Contrast": ["Black/white/yellow", "High visibility", "Accessibility"],
|
| 2600 |
+
"Developer": ["Authentic VS Code colors", "Consolas/Monaco fonts", "Exact theme matching"]
|
| 2601 |
+
}
|
| 2602 |
+
|
| 2603 |
+
# Load saved theme and apply it
|
| 2604 |
+
current_theme_name = get_saved_theme()
|
| 2605 |
+
current_theme = THEME_CONFIGS[current_theme_name]["theme"]
|
| 2606 |
+
|
| 2607 |
+
# Main application with proper Gradio theming
|
| 2608 |
with gr.Blocks(
|
| 2609 |
+
title="AnyCoder - AI Code Generator",
|
| 2610 |
+
theme=current_theme,
|
| 2611 |
+
css="""
|
| 2612 |
+
.theme-info { font-size: 0.9em; opacity: 0.8; }
|
| 2613 |
+
.theme-description { padding: 8px 0; }
|
| 2614 |
+
.theme-status {
|
| 2615 |
+
padding: 10px;
|
| 2616 |
+
border-radius: 8px;
|
| 2617 |
+
background: rgba(34, 197, 94, 0.1);
|
| 2618 |
+
border: 1px solid rgba(34, 197, 94, 0.2);
|
| 2619 |
+
margin: 8px 0;
|
| 2620 |
+
}
|
| 2621 |
+
.restart-needed {
|
| 2622 |
+
padding: 12px;
|
| 2623 |
+
border-radius: 8px;
|
| 2624 |
+
background: rgba(255, 193, 7, 0.1);
|
| 2625 |
+
border: 1px solid rgba(255, 193, 7, 0.3);
|
| 2626 |
+
margin: 8px 0;
|
| 2627 |
+
text-align: center;
|
| 2628 |
+
}
|
| 2629 |
+
"""
|
| 2630 |
) as demo:
|
| 2631 |
history = gr.State([])
|
| 2632 |
setting = gr.State({
|
|
|
|
| 2639 |
with gr.Sidebar():
|
| 2640 |
login_button = gr.LoginButton()
|
| 2641 |
|
| 2642 |
+
# Theme Selector (hidden for end users, developers can modify code)
|
| 2643 |
+
with gr.Column(visible=False):
|
| 2644 |
+
theme_dropdown = gr.Dropdown(
|
| 2645 |
+
choices=list(THEME_CONFIGS.keys()),
|
| 2646 |
+
value=current_theme_name,
|
| 2647 |
+
label="Select Theme",
|
| 2648 |
+
info="Choose your preferred visual style"
|
| 2649 |
+
)
|
| 2650 |
+
theme_description = gr.Markdown("")
|
| 2651 |
+
apply_theme_btn = gr.Button("Apply Theme", variant="primary", size="sm")
|
| 2652 |
+
theme_status = gr.Markdown("")
|
| 2653 |
+
|
| 2654 |
# Add Load Project section
|
| 2655 |
gr.Markdown("📥 Load Existing Project")
|
| 2656 |
load_project_url = gr.Textbox(
|
|
|
|
| 2914 |
outputs=[space_name_input, deploy_btn]
|
| 2915 |
)
|
| 2916 |
|
| 2917 |
+
# Theme switching handlers
|
| 2918 |
+
def handle_theme_change(theme_name):
|
| 2919 |
+
"""Handle theme selection change and update description"""
|
| 2920 |
+
if theme_name in THEME_CONFIGS:
|
| 2921 |
+
description = THEME_CONFIGS[theme_name]["description"]
|
| 2922 |
+
features = THEME_FEATURES.get(theme_name, [])
|
| 2923 |
+
feature_text = f"**Features:** {', '.join(features)}" if features else ""
|
| 2924 |
+
full_description = f"*{description}*\n\n{feature_text}"
|
| 2925 |
+
|
| 2926 |
+
return gr.update(value=full_description)
|
| 2927 |
+
return gr.update()
|
| 2928 |
+
|
| 2929 |
+
def apply_theme_change(theme_name):
|
| 2930 |
+
"""Save theme preference and show restart instruction"""
|
| 2931 |
+
if theme_name in THEME_CONFIGS:
|
| 2932 |
+
save_theme_preference(theme_name)
|
| 2933 |
+
|
| 2934 |
+
restart_message = f"""
|
| 2935 |
+
🎨 **Theme saved:** {theme_name}
|
| 2936 |
+
|
| 2937 |
+
⚠️ **Restart required** to fully apply the new theme.
|
| 2938 |
+
|
| 2939 |
+
**Why restart is needed:** Gradio themes are set during application startup and cannot be changed dynamically at runtime. This ensures all components are properly styled with consistent theming.
|
| 2940 |
+
|
| 2941 |
+
**To apply your new theme:**
|
| 2942 |
+
1. Stop the application (Ctrl+C)
|
| 2943 |
+
2. Restart it with the same command
|
| 2944 |
+
3. Your theme will be automatically loaded
|
| 2945 |
+
|
| 2946 |
+
*Your theme preference has been saved and will persist across restarts.*
|
| 2947 |
+
"""
|
| 2948 |
+
|
| 2949 |
+
return gr.update(value=restart_message, visible=True, elem_classes=["restart-needed"])
|
| 2950 |
+
return gr.update()
|
| 2951 |
+
|
| 2952 |
+
# Theme dropdown change event
|
| 2953 |
+
theme_dropdown.change(
|
| 2954 |
+
handle_theme_change,
|
| 2955 |
+
inputs=[theme_dropdown],
|
| 2956 |
+
outputs=[theme_description]
|
| 2957 |
+
)
|
| 2958 |
+
|
| 2959 |
+
# Apply theme button click event
|
| 2960 |
+
apply_theme_btn.click(
|
| 2961 |
+
apply_theme_change,
|
| 2962 |
+
inputs=[theme_dropdown],
|
| 2963 |
+
outputs=[theme_status]
|
| 2964 |
+
)
|
| 2965 |
+
|
| 2966 |
# Deploy to Spaces logic
|
| 2967 |
|
| 2968 |
def deploy_to_user_space(
|