chore: 初始化仓库基线(AGENTS.md、git 规范、敏感文件排除)

This commit is contained in:
weijuesen
2026-08-10 22:30:53 +08:00
commit 84abf4454c
358 changed files with 75993 additions and 0 deletions
+232
View File
@@ -0,0 +1,232 @@
import React, { useEffect } from 'react';
import { NavigationContainer, useNavigation } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { Provider as PaperProvider, useTheme, MD3LightTheme } from 'react-native-paper';
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
import { setNavigationRef } from '../api/client';
import { useAuthStore } from '../store/authStore';
import { useAppStore } from '../store/appStore';
import { wsManager } from '../utils/ws';
import type { RootStackParamList, MainTabParamList } from '../types';
import LoginScreen from '../screens/LoginScreen';
import DashboardScreen from '../screens/DashboardScreen';
import RoomsScreen from '../screens/RoomsScreen';
import RoomDetailScreen from '../screens/RoomDetailScreen';
import DevicesScreen from '../screens/DevicesScreen';
import DeviceControlScreen from '../screens/DeviceControlScreen';
import AlertsScreen from '../screens/AlertsScreen';
import ThresholdsScreen from '../screens/ThresholdsScreen';
import VideoScreen from '../screens/VideoScreen';
import VideoPlayerScreen from '../screens/VideoPlayerScreen';
import SettingsScreen from '../screens/SettingsScreen';
const Stack = createNativeStackNavigator<RootStackParamList>();
const Tab = createBottomTabNavigator<MainTabParamList>();
const TabIcon: React.FC<{ name: string; activeName: string; color: string; size: number; focused: boolean }> = ({ name, activeName, color, size, focused }) => (
<Icon name={focused ? activeName : name} size={focused ? 26 : 22} color={color} />
);
function MainTabs() {
const navigation = useNavigation<any>();
return (
<Tab.Navigator
screenOptions={{
headerShown: true,
tabBarActiveTintColor: '#5C7D60',
tabBarInactiveTintColor: '#C4BFB6',
tabBarStyle: {
backgroundColor: '#FFFFFF',
borderTopColor: '#F0EDE8',
borderTopWidth: 1,
paddingBottom: 6,
paddingTop: 6,
height: 60,
},
tabBarLabelStyle: {
fontSize: 15,
fontWeight: '700',
marginTop: 2,
},
tabBarIconStyle: {
marginBottom: 2,
},
headerStyle: {
backgroundColor: '#FAF8F5',
},
headerTitleStyle: {
color: '#2D2A26',
fontSize: 18,
fontWeight: '500',
},
headerTintColor: '#5C7D60',
headerRight: () => (
<Icon
name="cog-outline"
size={24}
color="#8C8780"
style={{ marginRight: 12 }}
onPress={() => navigation.navigate('Settings')}
/>
),
}}
>
<Tab.Screen
name="Dashboard"
component={DashboardScreen}
options={{
title: '仪表盘',
tabBarIcon: ({ color, size, focused }) => <TabIcon name="view-dashboard-outline" activeName="view-dashboard" color={color} size={size} focused={focused} />,
}}
/>
<Tab.Screen
name="Rooms"
component={RoomsScreen}
options={{
title: '蚕房',
tabBarIcon: ({ color, size, focused }) => <TabIcon name="home-outline" activeName="home-variant" color={color} size={size} focused={focused} />,
}}
/>
<Tab.Screen
name="Devices"
component={DevicesScreen}
options={{
title: '设备',
tabBarIcon: ({ color, size, focused }) => <TabIcon name="router-wireless" activeName="router-wireless" color={color} size={size} focused={focused} />,
}}
/>
<Tab.Screen
name="Alerts"
component={AlertsScreen}
options={{
title: '告警',
tabBarIcon: ({ color, size, focused }) => <TabIcon name="bell-alert-outline" activeName="bell-alert" color={color} size={size} focused={focused} />,
}}
/>
<Tab.Screen
name="Video"
component={VideoScreen}
options={{
title: '视频',
tabBarIcon: ({ color, size, focused }) => <TabIcon name="video-outline" activeName="video" color={color} size={size} focused={focused} />,
}}
/>
</Tab.Navigator>
);
}
function AppContent() {
const token = useAuthStore((s) => s.token);
const restoreSession = useAuthStore((s) => s.restoreSession);
const setRealtimeData = useAppStore((s) => s.setRealtimeData);
const [isReady, setIsReady] = React.useState(false);
useEffect(() => {
(async () => {
await restoreSession();
setIsReady(true);
})();
}, [restoreSession]);
// Subscribe to WebSocket telemetry
useEffect(() => {
const unsub = wsManager.subscribe((data) => {
if (data?.type === 'telemetry' || data?.metric) {
const telemetry = useAppStore.getState().realtimeData;
setRealtimeData([...telemetry, data].slice(-100));
}
});
return unsub;
}, [setRealtimeData]);
if (!isReady) {
return null;
}
return (
<NavigationContainer
ref={(ref) => {
if (ref) {
setNavigationRef({
navigate: (screen: string) => {
(ref as any).navigate(screen);
},
});
}
}}
>
<Stack.Navigator screenOptions={{ headerShown: false }} initialRouteName={token ? 'Main' : 'Login'}>
<Stack.Screen name="Login" component={LoginScreen} />
<Stack.Screen name="Main" component={MainTabs} />
<Stack.Screen
name="RoomDetail"
component={RoomDetailScreen}
options={{ headerShown: true, title: '蚕房详情', headerBackTitle: '返回' }}
/>
<Stack.Screen
name="DeviceControl"
component={DeviceControlScreen}
options={{ headerShown: true, title: '设备控制', headerBackTitle: '返回' }}
/>
<Stack.Screen
name="VideoPlayer"
component={VideoPlayerScreen}
options={{ headerShown: false }}
/>
<Stack.Screen
name="Thresholds"
component={ThresholdsScreen}
options={{ headerShown: true, title: '阈值管理', headerBackTitle: '返回' }}
/>
<Stack.Screen
name="Settings"
component={SettingsScreen}
options={{ headerShown: true, title: '设置', headerBackTitle: '返回' }}
/>
</Stack.Navigator>
</NavigationContainer>
);
}
export default function AppNavigator() {
const silkTheme = {
...MD3LightTheme,
colors: {
...MD3LightTheme.colors,
primary: '#7A9E7E',
primaryContainer: '#E8F0E9',
onPrimary: '#FFFFFF',
onPrimaryContainer: '#5C7D60',
secondary: '#6B8F71',
secondaryContainer: '#F0EDE8',
onSecondary: '#FFFFFF',
onSecondaryContainer: '#5C7D60',
error: '#D4847A',
errorContainer: '#F9E8E5',
onError: '#FFFFFF',
background: '#FAF8F5',
onBackground: '#2D2A26',
surface: '#FFFFFF',
onSurface: '#2D2A26',
surfaceVariant: '#F5F0E8',
onSurfaceVariant: '#8C8780',
outline: '#E8E4DE',
outlineVariant: '#F0EDE8',
elevation: {
...MD3LightTheme.colors.elevation,
level0: 'transparent',
level1: '#FFFFFF',
level2: '#FFFFFF',
},
},
};
return (
<PaperProvider theme={silkTheme}>
<AppContent />
</PaperProvider>
);
}