import { useCallback, useEffect, useState } from 'react' import { View, Text, ScrollView, StyleSheet, TextInput, Pressable, Switch, RefreshControl, } from 'react-native' import { SafeAreaView } from 'react-native-safe-area-context' import { useBind } from '@/context/BindContext' import { apiFetch } from '@/lib/api' import { theme } from '@/constants/theme' type ProxyState = { enabled: boolean; http: string; socks: string } export default function MoreScreen() { const { bind } = useBind() const [proxy, setProxy] = useState({ enabled: false, http: '', socks: '' }) const [metrics, setMetrics] = useState('') const [msg, setMsg] = useState('') const [refreshing, setRefreshing] = useState(false) const load = useCallback(async () => { if (!bind) return setMsg('') try { const pr = await apiFetch(bind, '/proxy_config') if (pr.ok) { const p = (await pr.json()) as ProxyState setProxy({ enabled: !!p.enabled, http: String(p.http || ''), socks: String(p.socks || ''), }) } const mr = await apiFetch(bind, '/system_metrics') if (mr.ok) { const m = await mr.json() setMetrics(JSON.stringify(m, null, 2)) } } catch (e) { setMsg(e instanceof Error ? e.message : String(e)) } }, [bind]) useEffect(() => { void load() }, [load]) const onRefresh = useCallback(async () => { setRefreshing(true) await load() setRefreshing(false) }, [load]) const saveProxy = useCallback(async () => { if (!bind) return try { const res = await apiFetch(bind, '/proxy_config', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(proxy), }) if (!res.ok) throw new Error(String(res.status)) setMsg('代理已保存') } catch (e) { setMsg(e instanceof Error ? e.message : String(e)) } }, [bind, proxy]) if (!bind) { return ( 请先完成配对 ) } return ( void onRefresh()} />} > 更多 录制代理(仅进程) 启用 setProxy((p) => ({ ...p, enabled: v }))} /> HTTP setProxy((p) => ({ ...p, http: t }))} placeholder="http://..." placeholderTextColor={theme.muted} autoCapitalize="none" /> SOCKS setProxy((p) => ({ ...p, socks: t }))} placeholder="socks5://..." placeholderTextColor={theme.muted} autoCapitalize="none" /> void saveProxy()}> 保存代理 系统指标 {metrics ? {metrics} : 加载中…} 微信 Chatbot 扫码登录与 Chatbot 配置依赖本机环境与桌面端逻辑,请在 Windows 控制台「微信」页完成。 {!!msg && {msg}} ) } const styles = StyleSheet.create({ safe: { flex: 1, backgroundColor: theme.bg }, scroll: { padding: 20, paddingBottom: 40 }, h1: { fontSize: 22, fontWeight: '700', color: theme.text, marginBottom: 16 }, card: { padding: 14, borderRadius: 12, backgroundColor: theme.bgCard, borderWidth: 1, borderColor: theme.border, marginBottom: 14, }, cardTitle: { fontSize: 15, fontWeight: '600', color: theme.text, marginBottom: 12 }, row: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', marginBottom: 12 }, label: { fontSize: 12, color: theme.muted, marginBottom: 6 }, input: { borderWidth: 1, borderColor: theme.border, borderRadius: 10, padding: 10, color: theme.text, marginBottom: 12, backgroundColor: theme.bg, }, btn: { backgroundColor: '#3d7eff', paddingVertical: 12, borderRadius: 10, alignItems: 'center', }, btnText: { color: '#fff', fontWeight: '700' }, pre: { fontFamily: 'monospace', fontSize: 10, color: '#c8cdd5', lineHeight: 16, }, muted: { color: theme.muted, fontSize: 13, lineHeight: 20 }, ok: { color: theme.success, marginTop: 8 }, })