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(
|