LifeFlow-AI / ui /components /input_form.py
Marco310's picture
feat: Optimize UI/UX
a3b49e8
raw
history blame
5.11 kB
import gradio as gr
def create_input_form(agent_stream_html):
"""創建優化後的輸入表單 - 放棄 gr.Examples,改用純按鈕"""
with gr.Group(elem_classes="glass-card") as input_area:
gr.Markdown("### 📝 What's your plan today?")
# 1. 主要輸入區
user_input = gr.Textbox(
label="Describe your tasks",
placeholder="e.g., I need to visit the dentist at 10am...",
lines=3,
elem_id="main-input"
)
# 2. 位置設定 (保持不變)
with gr.Accordion("📍 Location Settings", open=True):
auto_location = gr.Checkbox(label="Auto-detect my location", value=False)
with gr.Group(visible=True) as location_inputs:
with gr.Row():
lat_input = gr.Number(label="Latitude", value=25.033, precision=6, scale=1)
lon_input = gr.Number(label="Longitude", value=121.565, precision=6, scale=1)
# 3. 快速範例 (⭐⭐ 重製版:使用 Button 取代 Examples ⭐⭐)
gr.Markdown("##### ⚡ Quick Start Examples")
# 定義範例文字
ex_text_1 = "Plan a trip to visit Taipei 101, then have lunch at Din Tai Fung."
ex_text_2 = "Errands run: Post office, bank, and supermarket. Start at 10 AM, finish by 1 PM."
with gr.Column(elem_classes="example-container"):
# 這是真的按鈕,絕對會垂直排列,絕對不會被壓縮
btn_ex1 = gr.Button(ex_text_1, size="sm", variant="secondary", elem_classes="example-btn")
btn_ex2 = gr.Button(ex_text_2, size="sm", variant="secondary", elem_classes="example-btn")
# 4. 主按鈕
analyze_btn = gr.Button("🚀 Analyze & Plan Trip", variant="primary", size="lg")
# 5. Agent 狀態區
gr.Markdown("---")
gr.Markdown("### 🤖 Agent Status")
agent_stream_output = gr.HTML(
value=agent_stream_html,
elem_classes="agent-stream-box-step1",
visible=True
)
geo_js = """
(is_auto, curr_lat, curr_lon) => {
if (!is_auto) {
// 如果是「取消勾選」,保持原值不變
return [curr_lat, curr_lon];
}
// 如果是「勾選」,開始定位
return new Promise((resolve) => {
if (!navigator.geolocation) {
alert("Geolocation is not supported by your browser.");
resolve([curr_lat, curr_lon]); // 失敗回傳原值
return;
}
// 顯示讀取中的狀態 (可選)
// document.body.style.cursor = 'wait';
navigator.geolocation.getCurrentPosition(
(position) => {
// document.body.style.cursor = 'default';
// 成功!回傳經緯度
resolve([position.coords.latitude, position.coords.longitude]);
},
(error) => {
// document.body.style.cursor = 'default';
let msg = "Unknown error";
switch(error.code) {
case 1: msg = "Permission denied. Please allow location access."; break;
case 2: msg = "Position unavailable."; break;
case 3: msg = "Timeout."; break;
}
alert("📍 Location Error: " + msg);
resolve([curr_lat, curr_lon]); // 失敗回傳原值
},
{ enableHighAccuracy: true, timeout: 8000 }
);
});
}
"""
# 綁定事件 1: 控制輸入框顯示/隱藏 (Python 邏輯)
auto_location.change(
fn=lambda x: gr.update(visible=not x),
inputs=[auto_location],
outputs=[location_inputs]
)
# 綁定事件 2: 執行 JS 定位 (JS 邏輯)
# 注意 inputs 包含了 lat/lon,這樣 JS 才能在失敗/取消時把原值傳回來
auto_location.change(
fn=None,
inputs=[auto_location, lat_input, lon_input],
outputs=[lat_input, lon_input],
js=geo_js
)
# ⭐⭐ 綁定點擊事件 ⭐⭐
# 點擊按鈕 -> 把按鈕文字填入 user_input
btn_ex1.click(lambda: ex_text_1, outputs=user_input)
btn_ex2.click(lambda: ex_text_2, outputs=user_input)
return (input_area, agent_stream_output, user_input, auto_location,
location_inputs, lat_input, lon_input, analyze_btn)
def toggle_location_inputs(auto_loc):
return gr.update(visible=not auto_loc)