r0cketboy's picture
Update app.py from anycoder
00367c9 verified
import gradio as gr
import os
from pathlib import Path
def load_css():
"""Load CSS content for the application"""
return """
/* Main wrapper styling */
#main-wrapper {
min-height: 100vh;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
position: relative;
}
/* Header row styling */
#header-row {
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(10px);
border-bottom: 1px solid rgba(255, 255, 255, 0.2);
padding: 1rem;
border-radius: 0 0 15px 15px;
margin-bottom: 2rem;
}
/* Theme column styling */
#theme-col {
background: rgba(255, 255, 255, 0.05);
}
/* Info box styling */
.info-box {
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(10px);
padding: 0.75rem;
border-radius: 12px;
border: 1px solid rgba(255, 255, 255, 0.2);
margin-bottom: 1rem;
}
.info-box.success {
border-left: 4px solid #38a169;
}
.info-box.warning {
border-left: 4px solid #d69e2e;
}
.info-box.info {
border-left: 4px solid #4299e1;
}
.info-box-content {
padding: 1rem;
}
"""
def chat_wrapper(message, chat_history, first_time):
"""Wrapper function for chat interactions"""
if not message:
return message, chat_history, first_time
# Add user message
chat_history.append({"role": "user", "content": message})
# Simulate Steve's response
steve_response = f"Ah, {message}! Das klingt nach einem guten Projekt!"
# Add assistant message
chat_history.append({"role": "assistant", "content": steve_response})
# If this is the first question, hide the info boxes
if first_time:
first_time = False
return "", chat_history, first_time
def show_intro_info(first_time):
"""Show introductory information boxes if first time"""
return first_time
def update_intro_visibility(first_time):
"""Update the visibility of the intro boxes based on first_time state"""
return gr.update(visible=first_time)
def main():
css_content = load_css()
custom_theme = gr.themes.Soft(
primary_hue="blue",
secondary_hue="indigo",
neutral_hue="slate",
font=gr.themes.GoogleFont("Inter"),
text_size="lg",
spacing_size="lg",
radius_size="md"
).set(
button_primary_background_fill="*primary_600",
button_primary_background_fill_hover="*primary_700",
block_title_text_weight="600",
button_primary_text_color="white"
)
# JavaScript commands for theme switching
js_set_default = """
function(x) {
document.documentElement.setAttribute('data-theme', 'default');
return x;
"""
js_set_night = """
function(x) {
document.documentElement.setAttribute('data-theme', 'night');
return x;
"""
js_set_forest = """
function(x) {
document.documentElement.setAttribute('data-theme', 'forest');
return x;
"""
with gr.Blocks() as demo:
# State variables
menu_visible = gr.State(False)
first_time = gr.State(True)
with gr.Column(elem_id="main-wrapper"):
with gr.Row(elem_id="header-row"):
with gr.Column(scale=1, min_width=150, elem_id="theme-col"):
theme_btn = gr.Button("Themes", elem_id="theme-btn")
with gr.Group(visible=False, elem_id="theme-menu-group") as theme_menu:
btn_default = gr.Button("Tag", size="sm", elem_classes=["menu-btn"])
btn_night = gr.Button("Nacht", size="sm", elem_classes=["menu-btn"])
btn_forest = gr.Button("Wald", size="sm", elem_classes=["menu-btn"])
with gr.Column(scale=4):
pass
with gr.Column(scale=1, min_width=80, elem_id="crafting-col"):
gr.Image(
value="./chatbot/assets/crafting_table.png",
elem_id="crafting-table",
show_label=False,
show_download_button=False,
container=False,
interactive=False
)
# Chat Area
chatbot = gr.Chatbot(
value=[],
type="messages",
elem_id="minecraft-chat",
show_label=False,
bubble_full_width=False,
)
# Introductory Information Boxes (Visible only on first load)
with gr.Column(visible=True) as intro_boxes:
with gr.Group(elem_classes=["info-box", "success"]):
gr.Markdown("""
# 🎮 Willkommen beim Minecraft-Chatbot!
### ℹ️ Wichtige Informationen:
- **Steve** ist hier, um dir zu helfen!
- Du kannst über alles fragen - Crafting, Bauen, oder Abenteuer
""",
elem_classes=["info-box-content"]
)
with gr.Group(elem_classes=["info-box", "warning"]):
gr.Markdown("""
**⚠️ Achtung:** Diese Info-Boxen verschwinden nach deiner ersten Frage!
""",
elem_classes=["info-box-content"]
)
with gr.Group(elem_classes=["info-box", "info"]):
gr.Markdown("""
💡 **Tipp:** Frag mich nach:
- Crafting-Rezepten
- Bau-Ideen
- Minecraft-Tipps
""",
elem_classes=["info-box-content"]
)
with gr.Group(elem_id="footer-area"):
with gr.Row(elem_id="input-row"):
msg_box = gr.Textbox(
placeholder="Was möchtest du craften?",
show_label=False,
container=False,
elem_id="minecraft-input",
autofocus=True,
scale=1
)
send_btn = gr.Button("Senden", elem_id="minecraft-send-btn", scale=0)
# --- EVENT LOGIK FOR THE MENU ---
# 1. Menu open/close
def toggle_menu(is_visible):
return not is_visible, gr.update(visible=not is_visible)
theme_btn.click(
fn=toggle_menu,
inputs=[menu_visible],
outputs=[menu_visible, theme_menu],
api_visibility="public"
)
# 2. Theme Buttons: Execute JS AND close the menu
btn_default.click(
fn=None,
inputs=None,
outputs=[menu_visible, theme_menu],
js=js_set_default,
api_visibility="public"
).then(
fn=lambda: (False, gr.update(visible=False)),
outputs=[menu_visible, theme_menu],
api_visibility="public"
)
btn_night.click(
fn=None,
inputs=None,
outputs=[menu_visible, theme_menu],
api_visibility="public"
).then(
fn=lambda: (False, gr.update(visible=False)),
outputs=[menu_visible, theme_menu],
api_visibility="public"
)
btn_forest.click(
fn=None,
inputs=None,
outputs=[menu_visible, theme_menu],
api_visibility="public"
)
# --- CHAT EVENTS ---
msg_box.submit(
chat_wrapper,
inputs=[msg_box, chatbot, first_time],
outputs=[msg_box, chatbot, first_time],
api_visibility="public"
)
send_btn.click(
chat_wrapper,
inputs=[msg_box, chatbot, first_time],
outputs=[msg_box, chatbot, first_time],
api_visibility="public"
)
# Hide intro boxes when first_time becomes False
first_time.change(
fn=update_intro_visibility,
inputs=[first_time],
outputs=[intro_boxes],
api_visibility="public"
)
demo.launch(
inbrowser=True,
allowed_paths=["./chatbot/assets"],
theme=custom_theme,
css=css_content,
footer_links=[{"label": "Built with anycoder", "url": "https://huggingface.co/spaces/akhaliq/anycoder"}]
)
if __name__ == "__main__":
main()