/** * Cosmo - Deep Space Explorer * Main application component */ import { useState, useCallback } from 'react'; import { useSpaceData } from './hooks/useSpaceData'; import { useHistoricalData } from './hooks/useHistoricalData'; import { useTrajectory } from './hooks/useTrajectory'; import { Header } from './components/Header'; import { Scene } from './components/Scene'; import { ProbeList } from './components/ProbeList'; import { TimelineController } from './components/TimelineController'; import { Loading } from './components/Loading'; import type { CelestialBody } from './types'; // Timeline configuration - will be fetched from backend later const TIMELINE_DAYS = 30; // Total days in timeline range function App() { const [selectedDate, setSelectedDate] = useState(null); const [isTimelineMode, setIsTimelineMode] = useState(false); // Use real-time data or historical data based on mode const { bodies: realTimeBodies, loading: realTimeLoading, error: realTimeError } = useSpaceData(); const { bodies: historicalBodies, loading: historicalLoading, error: historicalError } = useHistoricalData(selectedDate); const bodies = isTimelineMode ? historicalBodies : realTimeBodies; const loading = isTimelineMode ? historicalLoading : realTimeLoading; const error = isTimelineMode ? historicalError : realTimeError; const [selectedBody, setSelectedBody] = useState(null); const { trajectoryPositions } = useTrajectory(selectedBody); // Handle time change from timeline controller const handleTimeChange = useCallback((date: Date) => { setSelectedDate(date); }, []); // Toggle timeline mode const toggleTimelineMode = useCallback(() => { setIsTimelineMode((prev) => !prev); if (!isTimelineMode) { // Entering timeline mode, set initial date to now (will play backward) setSelectedDate(new Date()); } else { setSelectedDate(null); } }, [isTimelineMode]); // Filter probes and planets from all bodies const probes = bodies.filter((b) => b.type === 'probe'); const planets = bodies.filter((b) => b.type === 'planet' || b.type === 'dwarf_planet' || b.type === 'satellite' ); const handleBodySelect = (body: CelestialBody | null) => { setSelectedBody(body); }; // Only show full screen loading when we have no data // This prevents flashing when timeline is playing and fetching new data if (loading && bodies.length === 0) { return ; } if (error) { return (

数据加载失败

{error}

请确保后端 API 运行在 http://localhost:8000

); } return (
{/* Header with navigation and controls */}
{/* Probe List Sidebar */} {/* 3D Scene */} {/* Timeline Controller */} {isTimelineMode && ( )} {/* Instructions overlay */}
{selectedBody ? ( <>

聚焦模式

点击侧边栏的"返回太阳系视图"按钮

) : ( <>

太阳系俯视图

🖱️ 左键拖动: 旋转

🖱️ 右键拖动: 平移

🖱️ 滚轮: 缩放

点击左侧天体列表查看详情

)}
); } export default App;