import { ConnectionBadge } from '@/components/ui/ConnectionBadge'; import { useLMStudio } from '@/hooks/useLMStudio'; import { useThemeColor } from '@/hooks/useThemeColor'; import * as api from '@/services/lmStudioApi'; import { useAppStore } from '@/store/useAppStore'; import { buildServerConfig, isConfigChanged } from '@/utils/serverConfig'; import { Network } from 'lucide-react-native'; import React, { useState } from 'react'; import { ActivityIndicator, StyleSheet, Text, TouchableOpacity, View } from 'react-native'; import { LabeledInput } from './LabeledInput'; import { SettingsSection } from './SettingsSection'; function TestResultBox({ ok }: { ok: boolean }) { const colors = useThemeColor(); return ( {ok ? 'Connection successful. API is ready.' : 'Connection failed. Verify host and port.'} ); } export function ServerConnectionCard() { const colors = useThemeColor(); const serverConfig = useAppStore(state => state.serverConfig); const setServerConfig = useAppStore(state => state.setServerConfig); const isConnected = useAppStore(state => state.isConnected); const setIsConnected = useAppStore(state => state.setIsConnected); const { fetchModels } = useLMStudio(); const [host, setHost] = useState(serverConfig.host); const [port, setPort] = useState(serverConfig.port.toString()); const [apiKey, setApiKey] = useState(serverConfig.apiKey ?? ''); const [isTesting, setIsTesting] = useState(false); const [testResult, setTestResult] = useState(null); const form = { host, port, apiKey }; const currentConfig = buildServerConfig(form); const configChanged = isConfigChanged(form, serverConfig); const handleSaveConfig = () => { setServerConfig(currentConfig); setTestResult(null); }; const handleTestConnection = async () => { handleSaveConfig(); setIsTesting(true); setTestResult(null); const ok = await api.testConnection(currentConfig); setTestResult(ok); setIsConnected(ok); if (ok) { await fetchModels(); } setIsTesting(false); }; return ( LM Studio API {configChanged && ( Save Changes )} {isTesting ? ( ) : ( Test Connection )} {testResult !== null && } ); } const styles = StyleSheet.create({ cardHeader: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', marginBottom: 16, }, cardHeaderTitle: { flexDirection: 'row', alignItems: 'center', }, headerIcon: { marginRight: 8, }, cardTitle: { fontSize: 18, fontWeight: '700', }, divider: { height: 1, width: '100%', marginBottom: 16, }, buttonRow: { flexDirection: 'row', gap: 12, marginTop: 8, }, saveButton: { flex: 1, paddingVertical: 14, borderRadius: 12, alignItems: 'center', borderWidth: 1, }, saveButtonText: { fontSize: 15, fontWeight: '600', }, testButton: { flex: 2, paddingVertical: 14, borderRadius: 12, alignItems: 'center', }, testButtonDisabled: { opacity: 0.7, }, testButtonText: { fontSize: 15, fontWeight: '600', }, resultBox: { marginTop: 16, borderRadius: 12, padding: 14, }, resultText: { fontSize: 14, textAlign: 'center', fontWeight: '500', }, });