mirror of
https://github.com/ruvnet/RuView.git
synced 2026-08-28 02:55:52 +00:00
- Added IosRssiService to handle synthetic RSSI data for iOS. - Created WebRssiService to simulate RSSI scanning on the web. - Defined shared types for WifiNetwork and RssiService in rssi.service.ts. - Introduced simulation service to generate synthetic sensing data. - Implemented WebSocket service for real-time data handling with reconnection logic. - Established Zustand stores for managing application state related to MAT and pose data. - Developed theme context and utility functions for consistent styling and formatting. - Added type definitions for various application entities including API responses and sensing data. - Created utility functions for color mapping and URL validation. - Configured TypeScript settings for the mobile application.
103 lines
3.0 KiB
TypeScript
103 lines
3.0 KiB
TypeScript
import { useState } from 'react';
|
|
import { Pressable, TextInput, View } from 'react-native';
|
|
import { validateServerUrl } from '@/utils/urlValidator';
|
|
import { apiService } from '@/services/api.service';
|
|
import { ThemedText } from '@/components/ThemedText';
|
|
import { colors } from '@/theme/colors';
|
|
import { spacing } from '@/theme/spacing';
|
|
|
|
type ServerUrlInputProps = {
|
|
value: string;
|
|
onChange: (value: string) => void;
|
|
onSave: () => void;
|
|
};
|
|
|
|
export const ServerUrlInput = ({ value, onChange, onSave }: ServerUrlInputProps) => {
|
|
const [testResult, setTestResult] = useState('');
|
|
|
|
const validation = validateServerUrl(value);
|
|
|
|
const handleTest = async () => {
|
|
if (!validation.valid) {
|
|
setTestResult('✗ Invalid URL');
|
|
return;
|
|
}
|
|
|
|
const start = Date.now();
|
|
try {
|
|
await apiService.getStatus();
|
|
setTestResult(`✓ ${Date.now() - start}ms`);
|
|
} catch {
|
|
setTestResult('✗ Failed');
|
|
}
|
|
};
|
|
|
|
return (
|
|
<View>
|
|
<ThemedText preset="labelMd" style={{ marginBottom: spacing.sm }}>
|
|
Server URL
|
|
</ThemedText>
|
|
<TextInput
|
|
value={value}
|
|
onChangeText={onChange}
|
|
autoCapitalize="none"
|
|
autoCorrect={false}
|
|
placeholder="http://192.168.1.100:8080"
|
|
keyboardType="url"
|
|
placeholderTextColor={colors.textSecondary}
|
|
style={{
|
|
borderWidth: 1,
|
|
borderColor: validation.valid ? colors.border : colors.danger,
|
|
borderRadius: 10,
|
|
backgroundColor: colors.surface,
|
|
color: colors.textPrimary,
|
|
padding: spacing.sm,
|
|
marginBottom: spacing.sm,
|
|
}}
|
|
/>
|
|
{!validation.valid && (
|
|
<ThemedText preset="bodySm" style={{ color: colors.danger, marginBottom: spacing.sm }}>
|
|
{validation.error}
|
|
</ThemedText>
|
|
)}
|
|
|
|
<ThemedText preset="bodySm" style={{ color: colors.textSecondary, marginBottom: spacing.sm }}>
|
|
{testResult || 'Ready to test connection'}
|
|
</ThemedText>
|
|
|
|
<View style={{ flexDirection: 'row', gap: spacing.sm }}>
|
|
<Pressable
|
|
onPress={handleTest}
|
|
disabled={!validation.valid}
|
|
style={{
|
|
flex: 1,
|
|
paddingVertical: 10,
|
|
borderRadius: 8,
|
|
backgroundColor: validation.valid ? colors.accentDim : colors.surfaceAlt,
|
|
alignItems: 'center',
|
|
}}
|
|
>
|
|
<ThemedText preset="labelMd" style={{ color: colors.textPrimary }}>
|
|
Test Connection
|
|
</ThemedText>
|
|
</Pressable>
|
|
<Pressable
|
|
onPress={onSave}
|
|
disabled={!validation.valid}
|
|
style={{
|
|
flex: 1,
|
|
paddingVertical: 10,
|
|
borderRadius: 8,
|
|
backgroundColor: validation.valid ? colors.success : colors.surfaceAlt,
|
|
alignItems: 'center',
|
|
}}
|
|
>
|
|
<ThemedText preset="labelMd" style={{ color: colors.textPrimary }}>
|
|
Save
|
|
</ThemedText>
|
|
</Pressable>
|
|
</View>
|
|
</View>
|
|
);
|
|
};
|