From ce7204b0161575e7dfe2a2827ac688b8ac37d0b5 Mon Sep 17 00:00:00 2001 From: LukeMackin Date: Wed, 22 Jul 2026 17:56:15 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20Rules=20of=20Hooks=20=E2=80=94=20Termina?= =?UTF-8?q?l=20state=E6=8F=90=E5=8D=87=E5=88=B0App=E9=A1=B6=E5=B1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 移除JSX内IIFE(违反Rules of Hooks) - termCmd/termOut/termRunning→App顶层useState - 切换标签不再触发hook数量变化 --- packages/client-android/App.tsx | 58 ++++++++++++++++----------------- 1 file changed, 28 insertions(+), 30 deletions(-) diff --git a/packages/client-android/App.tsx b/packages/client-android/App.tsx index bd41b79..3f14445 100644 --- a/packages/client-android/App.tsx +++ b/packages/client-android/App.tsx @@ -28,6 +28,23 @@ export default function App() { // Connection state const [connStatus, setConnStatus] = useState<'disconnected' | 'connecting' | 'connected' | 'error'>('disconnected'); + // Terminal state + const [termCmd, setTermCmd] = useState(''); + const [termOut, setTermOut] = useState('Execute remote commands via Gateway MCP.\nType a shell command and press Execute.\n'); + const [termRunning, setTermRunning] = useState(false); + const runTermCmd = async () => { + if (!termCmd.trim() || termRunning) return; + const c = termCmd.trim(); setTermCmd(''); setTermRunning(true); + setTermOut(o => o + `$ ${c}\n`); + try { + const r = await fetch(`${gatewayUrl}/tools/exec`, { method:'POST', headers:{'Content-Type':'application/json'}, body:JSON.stringify({command:c}), signal:AbortSignal.timeout(30000) }); + if (!r.ok) throw new Error(`HTTP ${r.status}`); + const d = await r.json() as any; + setTermOut(o => o + (d.stdout||d.stderr||JSON.stringify(d)) + '\n'); + } catch(e:any) { setTermOut(o => o + `Error: ${e.message}\n`); } + finally { setTermRunning(false); } + }; + /** Send chat message to Gateway */ const sendMessage = async () => { const text = input.trim(); @@ -130,36 +147,17 @@ export default function App() { {/* ── Terminal Tab ── */} {tab === 'terminal' && ( - (() => { - const [cmd, setCmd] = useState(''); - const [out, setOut] = useState('Execute remote commands via Gateway MCP.\nType a shell command and press Execute.\n'); - const [running, setRunning] = useState(false); - const runCmd = async () => { - if (!cmd.trim() || running) return; - const c = cmd.trim(); setCmd(''); setRunning(true); - setOut(o => o + `$ ${c}\n`); - try { - const r = await fetch(`${gatewayUrl}/tools/exec`, { method:'POST', headers:{'Content-Type':'application/json'}, body:JSON.stringify({command:c}), signal:AbortSignal.timeout(30000) }); - if (!r.ok) throw new Error(`HTTP ${r.status}`); - const d = await r.json() as any; - setOut(o => o + (d.stdout||d.stderr||JSON.stringify(d)) + '\n'); - } catch(e:any) { setOut(o => o + `Error: ${e.message}\n`); } - finally { setRunning(false); } - }; - return ( - - - {out} - - - - - {running ? '...' : 'Run'} - - - - ); - })() + + + {termOut} + + + + + {termRunning ? '...' : 'Run'} + + + )} {/* ── Settings Tab ── */}