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)