feat: Terminal Tab — 远程exec命令执行界面

- Terminal标签: 命令输入+Run按钮+输出区域
- 等宽字体+绿字黑底终端风格
- 5个Tab: Chat/Term/Gateway/Device/Connection
This commit is contained in:
LukeMackin
2026-07-22 17:51:49 +08:00
parent aa45b258b2
commit c407f6c483

View File

@@ -11,7 +11,7 @@ import { DEFAULT_GATEWAY_CONFIG } from '@yuzu-gca/shared';
type Msg = { role: 'user' | 'assistant'; text: string; ts: number }; type Msg = { role: 'user' | 'assistant'; text: string; ts: number };
export default function App() { export default function App() {
const [tab, setTab] = useState<'chat' | 'settings' | 'device' | 'connection'>('chat'); const [tab, setTab] = useState<'chat' | 'terminal' | 'settings' | 'device' | 'connection'>('chat');
// Chat state // Chat state
const [messages, setMessages] = useState<Msg[]>([]); const [messages, setMessages] = useState<Msg[]>([]);
@@ -85,10 +85,10 @@ export default function App() {
{/* Tabs */} {/* Tabs */}
<View style={styles.tabBar}> <View style={styles.tabBar}>
{(['chat', 'settings', 'device', 'connection'] as const).map(t => ( {(['chat', 'terminal', 'settings', 'device', 'connection'] as const).map(t => (
<TouchableOpacity key={t} onPress={() => setTab(t)} style={[styles.tab, tab === t && styles.tabActive]}> <TouchableOpacity key={t} onPress={() => setTab(t)} style={[styles.tab, tab === t && styles.tabActive]}>
<Text style={[styles.tabText, tab === t && styles.tabTextActive]}> <Text style={[styles.tabText, tab === t && styles.tabTextActive]}>
{t === 'chat' ? 'Chat' : t === 'settings' ? 'Gateway' : t === 'device' ? 'Device' : (connStatus === 'connected' ? '🟢' : '⚫')} {t === 'chat' ? 'Chat' : t === 'terminal' ? 'Term' : t === 'settings' ? 'Gateway' : t === 'device' ? 'Device' : (connStatus === 'connected' ? '🟢' : '⚫')}
</Text> </Text>
</TouchableOpacity> </TouchableOpacity>
))} ))}
@@ -128,6 +128,29 @@ export default function App() {
</View> </View>
)} )}
{/* ── Terminal Tab ── */}
{tab === 'terminal' && (
<View style={styles.chatContainer}>
<View style={styles.termOutput}>
<ScrollView>
<Text style={styles.termText} selectable>Execute remote commands via Gateway MCP.{'\n'}Type a shell command and press Execute.{'\n'}</Text>
</ScrollView>
</View>
<View style={styles.inputBar}>
<TextInput
style={styles.chatInput}
placeholder="ls -la /home"
placeholderTextColor="#475569"
autoCapitalize="none"
autoCorrect={false}
/>
<TouchableOpacity style={styles.sendBtn}>
<Text style={styles.sendBtnText}>Run</Text>
</TouchableOpacity>
</View>
</View>
)}
{/* ── Settings Tab ── */} {/* ── Settings Tab ── */}
{tab === 'settings' && ( {tab === 'settings' && (
<ScrollView style={styles.body}> <ScrollView style={styles.body}>
@@ -245,6 +268,8 @@ const styles = StyleSheet.create({
conn_error: { backgroundColor: '#7f1d1d' }, conn_error: { backgroundColor: '#7f1d1d' },
conn_disconnected: { backgroundColor: '#1e293b' }, conn_disconnected: { backgroundColor: '#1e293b' },
connText: { fontSize: 16, color: '#e2e8f0' }, connText: { fontSize: 16, color: '#e2e8f0' },
termOutput: { flex: 1, backgroundColor: '#0a0f1a', margin: 8, borderRadius: 8, padding: 12 },
termText: { fontFamily: 'monospace', fontSize: 12, color: '#22c55e', lineHeight: 18 },
btn: { borderRadius: 8, padding: 14, marginTop: 16, alignItems: 'center' }, btn: { borderRadius: 8, padding: 14, marginTop: 16, alignItems: 'center' },
btnPrimary: { backgroundColor: '#1e40af' }, btnPrimary: { backgroundColor: '#1e40af' },
btnDanger: { backgroundColor: '#991b1b' }, btnDanger: { backgroundColor: '#991b1b' },